1360a0cab50414ee30924917159066e69ee4b38d3Rob Herring/* 2360a0cab50414ee30924917159066e69ee4b38d3Rob Herring Driver for VES1893 and VES1993 QPSK Demodulators 3ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 4c84ca7ce3ae5d80622c1cc1cfe21011f9cc15be7Joachim Eastwood Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> 5c84ca7ce3ae5d80622c1cc1cfe21011f9cc15be7Joachim Eastwood Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> 658dc5b53e1c1467e54bbbc47d56a4d5f8c478a31Joachim Eastwood Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> 7ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> 8ad8a15d99cf2c8ab8ac1ab28402c49ec2548358dJean-Christophe PLAGNIOL-VILLARD 9e91a5555df5883bbc204b0e1f8e0489d3f7f3f2eJean-Christophe PLAGNIOL-VILLARD This program is free software; you can redistribute it and/or modify 10ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD it under the terms of the GNU General Public License as published by 11ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD the Free Software Foundation; either version 2 of the License, or 12ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD (at your option) any later version. 13ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 14ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD This program is distributed in the hope that it will be useful, 15ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD but WITHOUT ANY WARRANTY; without even the implied warranty of 16ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 18ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD GNU General Public License for more details. 19ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 202515e8bbc5dca415c5a810b8d5c6aa6acec1903cDouglas Gilbert You should have received a copy of the GNU General Public License 21ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD along with this program; if not, write to the Free Software 22ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 24ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD*/ 25ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 26d5c669f13759e790caf158d319641757768713beJean-Christophe PLAGNIOL-VILLARD#include <linux/kernel.h> 27ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD#include <linux/module.h> 28ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD#include <linux/init.h> 29ee867d8eab1ffba8ace677eb6b62fba8c45d2e85Jean-Christophe PLAGNIOL-VILLARD#include <linux/string.h> 30ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD#include <linux/slab.h> 31ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD#include <linux/delay.h> 32ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 330d67c9e81351a2269f3ae0e8072cb1d463bf5bc6Douglas Gilbert#include "dvb_frontend.h" 34470e891b06b2971037b38020cb4b9e7e496500e6Rodolfo Giometti#include "ves1x93.h" 35ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 36ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD 37ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARDstruct ves1x93_state { 38ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD struct i2c_adapter* i2c; 39ec6754a7b9e90a1eba7f3b2812003bb51d3dcf30Jean-Christophe PLAGNIOL-VILLARD /* configuration settings */ 40655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches const struct ves1x93_config* config; 41b7c2b6157079811586180d13c44a1095b57c2d47Nicolas Ferre struct dvb_frontend frontend; 42655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches 43655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches /* previous uncorrected block counter */ 44655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches fe_spectral_inversion_t inversion; 45655ff266998ae4b3c8e8565bf30f60ceebe39b54Ludovic Desroches u8 *init_1x93_tab; 46b32313c614268ee1fac37d63eceb33413b2d84c0Josh Wu u8 *init_1x93_wtab; 47b32313c614268ee1fac37d63eceb33413b2d84c0Josh Wu u8 tab_size; 483349a4b9019b57876b25c694025d96f519b795bcBarry Song u8 demod_type; 4985594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson u32 frequency; 50a4412050149fb314420ecec8f9b9f8b3c9515ecfChristian Daudt}; 5128ea3f3649b2adbfd96fdf66a2a25acc8c0e17ebMarkus Mayer 52a4412050149fb314420ecec8f9b9f8b3c9515ecfChristian Daudtstatic int debug; 532440946c29a37ee616a92152972a3772bd2f293cSebastian Hesselbarth#define dprintk if (debug) printk 54a90921185fe5db3e02aecf473f0c54343ae17191Sebastian Hesselbarth 55a90921185fe5db3e02aecf473f0c54343ae17191Sebastian Hesselbarth#define DEMOD_VES1893 0 563fcdc0555f5043eded6312efce14cd8dd66f30f8Olof Johansson#define DEMOD_VES1993 1 573fcdc0555f5043eded6312efce14cd8dd66f30f8Olof Johansson 58b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johanssonstatic u8 init_1893_tab [] = { 59b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4, 605e9eaadb0b3fa8c12715d9761158ec328d7e9523Sebastian Hesselbarth 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, 6137078732998e51c2645db99e7434ccc6774dafedSebastian Hesselbarth 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 62b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00, 63ef43eff3447f30b4a3cfc61813902c2e57c20245Uwe Kleine-König 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 64360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 65360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 669cd11c0c47b8690b47e7573311ce5c483cb344edLinus Torvalds}; 67765d012c2389cc0481f04dcccd3949f1ba0969baTomasz Figa 68800974ac0420f8f81cd7ad4d33bdf179b890b282Dongjin Kimstatic u8 init_1993_tab [] = { 692107673e16e4a20a14fd25505fa1a81e273f9983Thomas Abraham 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c, 70a94f56abae464e5fb6cd327d52de005dc9b96ee2Kukjin Kim 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, 71b67a55125f1413902f7db6d167a8d9e4154386bfAlex Ling 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7215dfdfad2d4a7e99c005854090274d03f7bacd27Tomasz Figa 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10, 73e88d5ae61a00b602cdd6a6c07f9fe6fbcaad06d7Girish K S 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 7495e82941b73b4a8811299ad7b639157822c8c59dDoug Anderson 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 757e65df3899cef3193ec44a7870f9bdc1ee6af833Kukjin Kim 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 769dd51c9f778199d343ae55db8a7d084e27501211Sachin Kamat 0x00, 0x00, 0x0e, 0x80, 0x00 7734dcedfbf97bc1c91c20f341e4ff4f70e53a0644Chander Kashyap}; 78a94f56abae464e5fb6cd327d52de005dc9b96ee2Kukjin Kim 797e65df3899cef3193ec44a7870f9bdc1ee6af833Kukjin Kimstatic u8 init_1893_wtab[] = 800cfb1c8bec551c8eb7c6b263baebc9537d2b910cHaojian Zhuang{ 817d6ab9b8620bbca6718b36242113f4f069840641Rob Herring 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 827d6ab9b8620bbca6718b36242113f4f069840641Rob Herring 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, 8317bfcd3adc2c2002c1fdf990640bc36aec6a90b3Linus Walleij 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, 8417bfcd3adc2c2002c1fdf990640bc36aec6a90b3Linus Walleij 1,1,1,0,1,1 85360a0cab50414ee30924917159066e69ee4b38d3Rob Herring}; 8698d4f2acb91ac4a839eab6b92f02f57986af2197Simon Guinot 870d0632f523fa040b307688ae421a1debf79af2d7Thomas Petazzonistatic u8 init_1993_wtab[] = 880d0632f523fa040b307688ae421a1debf79af2d7Thomas Petazzoni{ 8998d4f2acb91ac4a839eab6b92f02f57986af2197Simon Guinot 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, 90360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1, 91b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, 92360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 1,1,1,0,1,1,1,1, 1,1,1,1,1 93360a0cab50414ee30924917159066e69ee4b38d3Rob Herring}; 949b47a4fb7760fabfbbc33b7d7703454684f36782Willy Tarreau 95360a0cab50414ee30924917159066e69ee4b38d3Rob Herringstatic int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data) 96360a0cab50414ee30924917159066e69ee4b38d3Rob Herring{ 97b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson u8 buf [] = { 0x00, reg, data }; 98ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinot struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; 99b014487044161b83010a9cbe336dbc41d2c38a0bOlof Johansson int err; 1002cc64b5655da65bbb6a760a722b5ab1f53f92cf7Maxime Hadjinlian 101360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { 102360a0cab50414ee30924917159066e69ee4b38d3Rob Herring dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); 1035492a1108bbd40e14a895c07b6a4952022e82f7cStefan Peter return -EREMOTEIO; 10437ae08c9395420dc1479bca17158a649a771831dThomas Petazzoni } 105f236f5aabe8ebd7824590ae82d701402ead237e7Arnaud Ebalard 10646ca506c43d64e11257a0a113701e9bcccf52416Arnaud Ebalard return 0; 107ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinot} 108ca7d94524ab3554b08f13de91674d570cb4a09b6Simon Guinot 109ecee1e47ab42ba3907d6bde7b2981e1006382071Simon Guinotstatic u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg) 1107f9871d9d30f25891e0c4da4c6284d9e66e702f5Simon Guinot{ 111afcad884252b171ff6f2ac78eb43c2f5db612dd0Tero Jaasko int ret; 112eee47b7c6eb44861fe9a6c7052fd8243a4beaea6Andrew Lunn u8 b0 [] = { 0x00, reg }; 113f24b56cbcd9d39cb2ed45b4b451f8614f9494c17Thomas Petazzoni u8 b1 [] = { 0 }; 114f24b56cbcd9d39cb2ed45b4b451f8614f9494c17Thomas Petazzoni struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, 115ee514b381e17958fde5b99cba506f31ea6589c0bSimon Baatz { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; 116ee514b381e17958fde5b99cba506f31ea6589c0bSimon Baatz 117767fc1ea92f70b5a97d43b79c146c2bee3eb6e83Jason Cooper ret = i2c_transfer (state->i2c, msg, 2); 118360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 119f24b56cbcd9d39cb2ed45b4b451f8614f9494c17Thomas Petazzoni if (ret != 2) return ret; 1204898de3d15d8ba34aa7a1b0f753a476d52ebdf92Barry Song 121448e7edefa929104c77fe1a1cce4aa8ffc77d291Jonas Jensen return b1[0]; 12281cf1e061d001fab44dbaa85fc4fbfb6da6713a1Kumar Gala} 1239857a7531ffcf35442f9ef707e4e0d94a7a7fb18Rohit Vaswani 1249857a7531ffcf35442f9ef707e4e0d94a7a7fb18Rohit Vaswanistatic int ves1x93_clr_bit (struct ves1x93_state* state) 125360a0cab50414ee30924917159066e69ee4b38d3Rob Herring{ 126e3e37bcab910a68616bc33145ed5c333825053acGregory CLEMENT msleep(10); 1272344a29a923b95bb28609da4038590c4131160ccArnaud Ebalard ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe); 12845e8815fc1b7ed66729bbbc9464228ee1769b580Arnaud Ebalard ves1x93_writereg (state, 0, state->init_1x93_tab[0]); 129491221451b9998cf182770f2b5f8b3a8b141dd81Florian Fainelli msleep(50); 130c7841473f7ecbff624809f31f36aab0df5041ef9Thomas Petazzoni return 0; 13119b85c086019e54c1976fdaf56e8923f7e568091Thomas Petazzoni} 132568fc0a321a7f3ae1c3626a4f471d49ff005779cGregory CLEMENT 1338aa0b019fe1400cc8861ead9ff4cd0ba9f4e11ceArnaud Ebalardstatic int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion) 1347837feff0d881835309fced7a7c4b5f32866d632Thomas Petazzoni{ 13519b85c086019e54c1976fdaf56e8923f7e568091Thomas Petazzoni u8 val; 1368ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo 1378ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo /* 138860c06f6c0620307b595aacb3ead9c439e9dd785Fabio Estevam * inversion on/off are interchanged because i and q seem to 1398ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo * be swapped on the hardware 14000ba2459f6d5f9caee01cf5628df553ace50cbcdGwenhael Goavec-Merou */ 1418ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo 14242a56fc6febad79f16a94391d89c617c140d6e7eAlexander Shiyan switch (inversion) { 143c05c1bf5739cb7adaa955503fc819d077bc46d25Alexander Shiyan case INVERSION_OFF: 144db890dad41d538f774e0e1f2f10613b1b083a96bMarkus Pargmann val = 0xc0; 145db890dad41d538f774e0e1f2f10613b1b083a96bMarkus Pargmann break; 1468ba472357a87503df2214ddc0270706ae34da4a1Shawn Guo case INVERSION_ON: 1471982d5b6c1b78363b5142eb0cb81c38d7604fc61Laurent Cans val = 0x80; 148e910b45c9d6413c057fc0aaf8616683446bdda7dGwenhael Goavec-Merou break; 1499c9651cd7412032657e4949dd5cbdd8f1364befdFabio Estevam case INVERSION_AUTO: 150360a0cab50414ee30924917159066e69ee4b38d3Rob Herring val = 0x00; 151360a0cab50414ee30924917159066e69ee4b38d3Rob Herring break; 152051124e596869ddf3efa7a2dc2f8209401e55d09Marek Vasut default: 153be3a568d77fac942bbc7fb5ed77963bc254e60ffSteffen Trumtrar return -EINVAL; 154360a0cab50414ee30924917159066e69ee4b38d3Rob Herring } 155360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 156971488f1149f09fd2fad0e7973780b752809b9f6Russell King return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val); 157208d7baf8085ed639ec896274f1679d4718f2ff3Russell King} 1581aa8b3e06f5fcc294b54fe2c35b2e34b09048e94Shawn Guo 1599a8d6d55f6989961298b995e3ef91eb90e034cf2Shawn Guostatic int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec) 16089b82915c4b5afa9e51e09636f7919bbb6f9cc1bFabio Estevam{ 161360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (fec == FEC_AUTO) 162971488f1149f09fd2fad0e7973780b752809b9f6Russell King return ves1x93_writereg (state, 0x0d, 0x08); 1633180f956668ee04d35d77b32a6a1be10fb251d9dChristian Hemp else if (fec < FEC_1_2 || fec > FEC_8_9) 1645c70cb01b89895189025f8de8ee2823f516eab6aFabio Estevam return -EINVAL; 165360a0cab50414ee30924917159066e69ee4b38d3Rob Herring else 1668593a1a2e88a0b23d3bd626eee6519de9ee55938Pavel Machek return ves1x93_writereg (state, 0x0d, fec - FEC_1_2); 167117ccd553a02a69aff41083f8b59a38927ccf002Shawn Guo} 16840cdaa542cf0c570600c29b006b782631d07d052Fabio Estevam 1692688a32f98774573d42a2a5cf024fd6caca00619Fabio Estevamstatic fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state) 170e77b74ee6c4115a0fe1fdb673dbf25ffe1277205Jingchang Lu{ 171931398ecd51bc7d6f3a22561c31bfd34d030c94aMatt Porter return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7); 172e77b74ee6c4115a0fe1fdb673dbf25ffe1277205Jingchang Lu} 173360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 174360a0cab50414ee30924917159066e69ee4b38d3Rob Herringstatic int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) 175360a0cab50414ee30924917159066e69ee4b38d3Rob Herring{ 176a957fdca4feb7fbc51f9c7c6a152a86f35ca7751Julien Boibessot u32 BDR; 177414b41536c4564db696d5fb18d8baf695491cd02Gwenhael Goavec-Merou u32 ratio; 178360a0cab50414ee30924917159066e69ee4b38d3Rob Herring u8 ADCONF, FCONF, FNR, AGCR; 179360a0cab50414ee30924917159066e69ee4b38d3Rob Herring u32 BDRI; 180e0f7d905242f5eedc4801ce588f7f588f4ec57cbMaxime Ripard u32 tmp; 1815ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson u32 FIN; 182ed138c368d95095de522db98b8b6929874bed403Brian Lilly 183f6cd16f1d2dae4e31aba8bb6a3cac21aba1416ceBrian Lilly dprintk("%s: srate == %d\n", __func__, (unsigned int) srate); 184d75f3d92e86e65b3cb9725e65f7278cc303511dbBrian Lilly 1859567832223f0aaa5ffed02307c2dc099a6640da8Brian Lilly if (srate > state->config->xin/2) 186360a0cab50414ee30924917159066e69ee4b38d3Rob Herring srate = state->config->xin/2; 187e0ec2f39ef9905a24d5d88238eda3dabb8d591e0Marek Vasut 188360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (srate < 500000) 189160d5f27605f5acac8f426d862e8f8a499eef2b5Marek Vasut srate = 500000; 190360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 191f8635abd38776a413d1e84c79353693b8ecf45c9Linus Walleij#define MUL (1UL<<26) 192d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tang 193d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tang FIN = (state->config->xin + 6000) >> 4; 194d907849e0dbaeacb34e0a6a3b49ebeaf8c49355eDaniel Tang 19585594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson tmp = srate << 6; 19604a25dfb7956284029b486b5c72657ebbf7b8c85Tony Lindgren ratio = tmp / FIN; 197a900f51646f5e77b5a7fc164bfb10eed55497861Tony Lindgren 198a900f51646f5e77b5a7fc164bfb10eed55497861Tony Lindgren tmp = (tmp % FIN) << 8; 199a900f51646f5e77b5a7fc164bfb10eed55497861Tony Lindgren ratio = (ratio << 8) + tmp / FIN; 200678fac41938299d33b980ad0e7b81438d3d88836Jon Hunter 2015a8095e9d02da19f3bab738e82c0520ecd62d6afJon Hunter tmp = (tmp % FIN) << 8; 2020f0cfc69547ea3e26f53e50eae2f25fe6ea1a77dTony Lindgren ratio = (ratio << 8) + tmp / FIN; 2030f0cfc69547ea3e26f53e50eae2f25fe6ea1a77dTony Lindgren 2044bfe6341d4bfcb68c083b3109b6a4997cd287262Anil Kumar FNR = 0xff; 20585594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson 20685594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson if (ratio < MUL/3) FNR = 0; 2075992234bc5f34f3069d0457090d87865ec31fe13Tony Lindgren if (ratio < (MUL*11)/50) FNR = 1; 208bd5fc6fa657cfe4b2de6e0f6e4daae41217392bdTony Lindgren if (ratio < MUL/6) FNR = 2; 209a4d4b15363ea31236e557c471d9aa95202fed88aPavel Machek if (ratio < MUL/9) FNR = 3; 210df01318850d5c687533c6e2460d1df65944d0d4bAaro Koskinen if (ratio < MUL/12) FNR = 4; 211df01318850d5c687533c6e2460d1df65944d0d4bAaro Koskinen if (ratio < (MUL*11)/200) FNR = 5; 21285594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson if (ratio < MUL/24) FNR = 6; 213adfe1473bda5bfb8d344a94fb17c0a929fcbd852Marek Belisko if (ratio < (MUL*27)/1000) FNR = 7; 214cb5e191e96953965aab8aa3bf4c0aee01faaaf79Javier Martinez Canillas if (ratio < MUL/48) FNR = 8; 2159ad1df2b15b0f1952a57c3407996450cc64bc976Javier Martinez Canillas if (ratio < (MUL*137)/10000) FNR = 9; 216c482525659effc9fadc0cef88cffdb6f8c63d2b6Tony Lindgren 21785594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson if (FNR == 0xff) { 21830a6998ef4474b18d81d8c459f2cbd9e49ff0736Jon Hunter ADCONF = 0x89; 21900cbdce75b62a56bf3e6baca68b5ddb5474495a2Benoit Cousson FCONF = 0x80; 22000cbdce75b62a56bf3e6baca68b5ddb5474495a2Benoit Cousson FNR = 0; 22185594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson } else { 22244b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard ADCONF = 0x81; 223fa63d037283a6bd0db96078d87192d1aaa073f3cSricharan R FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); 224f0cfa981cec09e6e353295e0f8dc36bc10289996Vaibhav Hiremath /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/ 2257340dd530c5f72e63201953677b42c9e5fdb2b3dBenoit Cousson } 22644b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard 2272ba3549352277514a8e4790adff77a783ee1b9e2Koen Kooi BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; 228c351e29018eeb2fa3151e09a9102e223519c34d5Mark Jackson BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; 2295cda1620f457459240176ab6abc9431a1ad6684aEnric Balletbo i Serra 23044b5b2d2d405c148545bef910d953e2323769a7cFlorian Vaussard dprintk("FNR= %d\n", FNR); 2314730bcfb067a92bd446b4ffd149e0768572c7f19Afzal Mohammed dprintk("ratio= %08x\n", (unsigned int) ratio); 2326e58b8f1daaf1af340fb9309907e5ffa473c7affR Sricharan dprintk("BDR= %08x\n", (unsigned int) BDR); 2336e58b8f1daaf1af340fb9309907e5ffa473c7affR Sricharan dprintk("BDRI= %02x\n", (unsigned int) BDRI); 23407f645df9ff2550749b806af626576d5ad418215Thomas Petazzoni 23585594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson if (BDRI > 0xff) 2362ce05a14bb379bd81ba3ad12cc08b2c4bda83480Linus Walleij BDRI = 0xff; 23701dc909fa1be6259cdbbc9fd6933df4fbe26ea5aLinus Walleij 23801dc909fa1be6259cdbbc9fd6933df4fbe26ea5aLinus Walleij ves1x93_writereg (state, 0x06, 0xff & BDR); 23901dc909fa1be6259cdbbc9fd6933df4fbe26ea5aLinus Walleij ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8)); 24001dc909fa1be6259cdbbc9fd6933df4fbe26ea5aLinus Walleij ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16)); 2412ce05a14bb379bd81ba3ad12cc08b2c4bda83480Linus Walleij 2422ce05a14bb379bd81ba3ad12cc08b2c4bda83480Linus Walleij ves1x93_writereg (state, 0x09, BDRI); 24335aca36450e6c3fb3b3fe9ea60a7c4689a219a87Heiko Stuebner ves1x93_writereg (state, 0x20, ADCONF); 2442ec35a4252eae3d5277af041bd1b5ae4f6183cadTomasz Figa ves1x93_writereg (state, 0x21, FCONF); 2452ec35a4252eae3d5277af041bd1b5ae4f6183cadTomasz Figa 246bf98c1eac1d4a6bcf00532e4fa41d8126cd6c187Laurent Pinchart AGCR = state->init_1x93_tab[0x05]; 247a4ed412ed5934127ba88ba007b9a00617ae47f75Magnus Damm if (state->config->invert_pwm) 248495e06d1daff7f59b511c27c95d2601c1d9dad49Magnus Damm AGCR |= 0x20; 24985594df2bad0dddb36aa8aa242f4d15e6f122f02Olof Johansson 25053e42c2974feaa269bc485267d0a4df0ef55e549Kuninori Morimoto if (srate < 6000000) 251cfa66a81621d0e85ac03c0de25adc7edd7f2649eKuninori Morimoto AGCR |= 0x80; 25276b92b4043f2303b443645b5609a8867e8a8b5d7Bastian Hecht else 253d6b51d6b6a33974dfa7b091f61e7a2bedd62f298Simon Horman AGCR &= ~0x80; 25473d6a69e3b3ae168fcb8d797e427c1b5fe132a40Simon Horman 2551f52c65975ba16cdba1830ba216776111197a3eeHisashi Nakamura ves1x93_writereg (state, 0x05, AGCR); 2563cc828fdb32281cc8166d3a40bee32b90ce3cad8Magnus Damm 2570ce53cdc5c7e28f378e480363a0b0c2ed7e7eaf9Nobuhiro Iwamatsu /* ves1993 hates this, will lose lock */ 258b8b82b2983e5b7bccca3a037c886e2aad86aaeeaSimon Horman if (state->demod_type != DEMOD_VES1993) 25978ded16886f539830ed58d9bc043656c1785a082Magnus Damm ves1x93_clr_bit (state); 26069f366615e950cb0d5af89da228796af5208ad8fGuennadi Liakhovetski 2610ce53cdc5c7e28f378e480363a0b0c2ed7e7eaf9Nobuhiro Iwamatsu return 0; 2626d75bc6439ec3f4ae45db1e501177382d0582591Magnus Damm} 2637d91c4691207a302c50308ab38706b8a3d6039cdMagnus Damm 2641d2bdbc3a8f93b8c1dfc95b2df89c266dd6ce9d0Laurent Pinchartstatic int ves1x93_init (struct dvb_frontend* fe) 2651d2bdbc3a8f93b8c1dfc95b2df89c266dd6ce9d0Laurent Pinchart{ 266163a036468c2eb8f30658dff6c0de6c959f79b0dDinh Nguyen struct ves1x93_state* state = fe->demodulator_priv; 267163a036468c2eb8f30658dff6c0de6c959f79b0dDinh Nguyen int i; 26847ba5c815a341899035a35f7b58fbe1f1deee880Steffen Trumtrar int val; 26990c294557d411100d3557bc2762a98a93f989430Dinh Nguyen 270360a0cab50414ee30924917159066e69ee4b38d3Rob Herring dprintk("%s: init chip\n", __func__); 271360a0cab50414ee30924917159066e69ee4b38d3Rob Herring 272360a0cab50414ee30924917159066e69ee4b38d3Rob Herring for (i = 0; i < state->tab_size; i++) { 273360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (state->init_1x93_wtab[i]) { 274e2eb69183ec4156eb814e67672e492bf902bbcd2Shiraz Hashim val = state->init_1x93_tab[i]; 275e2eb69183ec4156eb814e67672e492bf902bbcd2Shiraz Hashim 276360a0cab50414ee30924917159066e69ee4b38d3Rob Herring if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */ 277f1148dba64f3bf3a346e1eb7cdfac0e5f70660c8Srinivas Kandagatla ves1x93_writereg (state, i, val); 27840e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla } 27940e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla } 28040e3e6725370481b7b81d969dbde056f50d870aeSrinivas Kandagatla 281d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripard return 0; 282629ae88e9cebc6281bc54be743a33eca47b7228cEmilio López} 283d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripard 284d34c671debe3d327424a9951a5c3a81065d0474dMaxime Ripardstatic int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) 285a9d281cab72cbb45fcde8be3e20b7494f573ac9dMaxime Ripard{ 286d0f2677be5b49a1c1de59fe94faa96b7808be95fMaxime Ripard struct ves1x93_state* state = fe->demodulator_priv; 2870bef900b7fae00f2f58bffdeac3fd4dbae78c117Maxime Ripard 28852e86b37b1d3f7c02938def3a036e0bb0f723964Hans de Goede switch (voltage) { 289e476ac8b483de4ce1d8570509be343afc7cd3bafMaxime Ripard case SEC_VOLTAGE_13: 29082abe5294aeadc42508c7944f3a9aec0eece214cMaxime Ripard return ves1x93_writereg (state, 0x1f, 0x20); 29101ed6632a554dfdf4a9fc3c593ce4ff7255ed161Oliver Schinagl case SEC_VOLTAGE_18: 292e476ac8b483de4ce1d8570509be343afc7cd3bafMaxime Ripard return ves1x93_writereg (state, 0x1f, 0x30); 293360a0cab50414ee30924917159066e69ee4b38d3Rob Herring case SEC_VOLTAGE_OFF: 294bf5fcc76d31418950b214542440d5de6e48c7998Lucas Stach return ves1x93_writereg (state, 0x1f, 0x00); 2955ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson default: 296360a0cab50414ee30924917159066e69ee4b38d3Rob Herring return -EINVAL; 2975ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson } 298360a0cab50414ee30924917159066e69ee4b38d3Rob Herring} 2995ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson 300360a0cab50414ee30924917159066e69ee4b38d3Rob Herringstatic int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) 301360a0cab50414ee30924917159066e69ee4b38d3Rob Herring{ 302360a0cab50414ee30924917159066e69ee4b38d3Rob Herring struct ves1x93_state* state = fe->demodulator_priv; 303d7df69fe256587c5f78961c4d69a95d4a5b12c71Bryan Wu 3045ae8d15f686f93d2ac60a7b16d8ddfbfdfc7c00fOlof Johansson u8 sync = ves1x93_readreg (state, 0x0e); 305a71c03e7fd6a4027f750e2951830669244a8dad6Hiroshi Doyu 306a1425d428f39e5b95663f3f8037f372e86f2676fJoseph Lo /* 307a1425d428f39e5b95663f3f8037f372e86f2676fJoseph Lo * The ves1893 sometimes returns sync values that make no sense, 308cc8e9ad88487004372cae87718ff593d0a2fdc3aRob Herring * because, e.g., the SIGNAL bit is 0, while some of the higher 309cc8e9ad88487004372cae87718ff593d0a2fdc3aRob Herring * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?). 310978577ea21fb05c12511c25b71e493859e36892fLinus Walleij * Tests showed that the VITERBI and SYNC bits are returned 311360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong. 312360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * If such a case occurs, we read the value again, until we get a 313360a0cab50414ee30924917159066e69ee4b38d3Rob Herring * valid value. 314cc3d7f70c37641ca417f4c02ecaf12cd9772ffa6Stefano Stabellini */ 315cc3d7f70c37641ca417f4c02ecaf12cd9772ffa6Stefano Stabellini int maxtry = 10; /* just for safety - let's not get stuck here */ 316ed304be1b222398cd15954724e95787bb42e3b37Tony Prisk while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) { 317ed304be1b222398cd15954724e95787bb42e3b37Tony Prisk msleep(10); 318def4d6c044ea1f5f58ed6d422e6797fb0b1cfb63Tony Prisk sync = ves1x93_readreg (state, 0x0e); 3194606c48051db62db14756e1085fe0f8821a0e116Tony Prisk } 320def4d6c044ea1f5f58ed6d422e6797fb0b1cfb63Tony Prisk 3214bda2670e4759b99f725176dd31caa612ea098b6Soren Brinkmann *status = 0; 32250dbb4cfbc264b074759e8fb5d8e0c0496a1b072Soren Brinkmann 32350dbb4cfbc264b074759e8fb5d8e0c0496a1b072Soren Brinkmann if (sync & 1) 324360a0cab50414ee30924917159066e69ee4b38d3Rob Herring *status |= FE_HAS_SIGNAL; 325499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely 3261ab3681271c84b7f926be9ae3be1d769b7e933e9Stephen Warren if (sync & 2) 327360a0cab50414ee30924917159066e69ee4b38d3Rob Herring *status |= FE_HAS_CARRIER; 328499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely 329499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely if (sync & 4) 330499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely *status |= FE_HAS_VITERBI; 331499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely 332499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely if (sync & 8) 333499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely *status |= FE_HAS_SYNC; 334499cd8298628eeabf0eb5eb6525d4faa0eec80d8Grant Likely 335 if ((sync & 0x1f) == 0x1f) 336 *status |= FE_HAS_LOCK; 337 338 return 0; 339} 340 341static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) 342{ 343 struct ves1x93_state* state = fe->demodulator_priv; 344 345 *ber = ves1x93_readreg (state, 0x15); 346 *ber |= (ves1x93_readreg (state, 0x16) << 8); 347 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16); 348 *ber *= 10; 349 350 return 0; 351} 352 353static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) 354{ 355 struct ves1x93_state* state = fe->demodulator_priv; 356 357 u8 signal = ~ves1x93_readreg (state, 0x0b); 358 *strength = (signal << 8) | signal; 359 360 return 0; 361} 362 363static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) 364{ 365 struct ves1x93_state* state = fe->demodulator_priv; 366 367 u8 _snr = ~ves1x93_readreg (state, 0x1c); 368 *snr = (_snr << 8) | _snr; 369 370 return 0; 371} 372 373static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 374{ 375 struct ves1x93_state* state = fe->demodulator_priv; 376 377 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; 378 379 if (*ucblocks == 0x7f) 380 *ucblocks = 0xffffffff; /* counter overflow... */ 381 382 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */ 383 ves1x93_writereg (state, 0x18, 0x80); /* dto. */ 384 385 return 0; 386} 387 388static int ves1x93_set_frontend(struct dvb_frontend *fe) 389{ 390 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 391 struct ves1x93_state* state = fe->demodulator_priv; 392 393 if (fe->ops.tuner_ops.set_params) { 394 fe->ops.tuner_ops.set_params(fe); 395 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 396 } 397 ves1x93_set_inversion (state, p->inversion); 398 ves1x93_set_fec(state, p->fec_inner); 399 ves1x93_set_symbolrate(state, p->symbol_rate); 400 state->inversion = p->inversion; 401 state->frequency = p->frequency; 402 403 return 0; 404} 405 406static int ves1x93_get_frontend(struct dvb_frontend *fe) 407{ 408 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 409 struct ves1x93_state* state = fe->demodulator_priv; 410 int afc; 411 412 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; 413 afc = (afc * (int)(p->symbol_rate/1000/8))/16; 414 415 p->frequency = state->frequency - afc; 416 417 /* 418 * inversion indicator is only valid 419 * if auto inversion was used 420 */ 421 if (state->inversion == INVERSION_AUTO) 422 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ? 423 INVERSION_OFF : INVERSION_ON; 424 p->fec_inner = ves1x93_get_fec(state); 425 /* XXX FIXME: timing offset !! */ 426 427 return 0; 428} 429 430static int ves1x93_sleep(struct dvb_frontend* fe) 431{ 432 struct ves1x93_state* state = fe->demodulator_priv; 433 434 return ves1x93_writereg (state, 0x00, 0x08); 435} 436 437static void ves1x93_release(struct dvb_frontend* fe) 438{ 439 struct ves1x93_state* state = fe->demodulator_priv; 440 kfree(state); 441} 442 443static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) 444{ 445 struct ves1x93_state* state = fe->demodulator_priv; 446 447 if (enable) { 448 return ves1x93_writereg(state, 0x00, 0x11); 449 } else { 450 return ves1x93_writereg(state, 0x00, 0x01); 451 } 452} 453 454static struct dvb_frontend_ops ves1x93_ops; 455 456struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, 457 struct i2c_adapter* i2c) 458{ 459 struct ves1x93_state* state = NULL; 460 u8 identity; 461 462 /* allocate memory for the internal state */ 463 state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL); 464 if (state == NULL) goto error; 465 466 /* setup the state */ 467 state->config = config; 468 state->i2c = i2c; 469 state->inversion = INVERSION_OFF; 470 471 /* check if the demod is there + identify it */ 472 identity = ves1x93_readreg(state, 0x1e); 473 switch (identity) { 474 case 0xdc: /* VES1893A rev1 */ 475 printk("ves1x93: Detected ves1893a rev1\n"); 476 state->demod_type = DEMOD_VES1893; 477 state->init_1x93_tab = init_1893_tab; 478 state->init_1x93_wtab = init_1893_wtab; 479 state->tab_size = sizeof(init_1893_tab); 480 break; 481 482 case 0xdd: /* VES1893A rev2 */ 483 printk("ves1x93: Detected ves1893a rev2\n"); 484 state->demod_type = DEMOD_VES1893; 485 state->init_1x93_tab = init_1893_tab; 486 state->init_1x93_wtab = init_1893_wtab; 487 state->tab_size = sizeof(init_1893_tab); 488 break; 489 490 case 0xde: /* VES1993 */ 491 printk("ves1x93: Detected ves1993\n"); 492 state->demod_type = DEMOD_VES1993; 493 state->init_1x93_tab = init_1993_tab; 494 state->init_1x93_wtab = init_1993_wtab; 495 state->tab_size = sizeof(init_1993_tab); 496 break; 497 498 default: 499 goto error; 500 } 501 502 /* create dvb_frontend */ 503 memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); 504 state->frontend.demodulator_priv = state; 505 return &state->frontend; 506 507error: 508 kfree(state); 509 return NULL; 510} 511 512static struct dvb_frontend_ops ves1x93_ops = { 513 .delsys = { SYS_DVBS }, 514 .info = { 515 .name = "VLSI VES1x93 DVB-S", 516 .frequency_min = 950000, 517 .frequency_max = 2150000, 518 .frequency_stepsize = 125, /* kHz for QPSK frontends */ 519 .frequency_tolerance = 29500, 520 .symbol_rate_min = 1000000, 521 .symbol_rate_max = 45000000, 522 /* .symbol_rate_tolerance = ???,*/ 523 .caps = FE_CAN_INVERSION_AUTO | 524 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 525 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 526 FE_CAN_QPSK 527 }, 528 529 .release = ves1x93_release, 530 531 .init = ves1x93_init, 532 .sleep = ves1x93_sleep, 533 .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, 534 535 .set_frontend = ves1x93_set_frontend, 536 .get_frontend = ves1x93_get_frontend, 537 538 .read_status = ves1x93_read_status, 539 .read_ber = ves1x93_read_ber, 540 .read_signal_strength = ves1x93_read_signal_strength, 541 .read_snr = ves1x93_read_snr, 542 .read_ucblocks = ves1x93_read_ucblocks, 543 544 .set_voltage = ves1x93_set_voltage, 545}; 546 547module_param(debug, int, 0644); 548 549MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver"); 550MODULE_AUTHOR("Ralph Metzler"); 551MODULE_LICENSE("GPL"); 552 553EXPORT_SYMBOL(ves1x93_attach); 554