/*
Samsung S5H1409 VSB/QAM demodulator driver
Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "s5h1409.h"
struct s5h1409_state {
struct i2c_adapter *i2c;
/* configuration settings */
const struct s5h1409_config *config;
struct dvb_frontend frontend;
/* previous uncorrected block counter */
fe_modulation_t current_modulation;
u32 current_frequency;
int if_freq;
u32 is_qam_locked;
u32 qam_state;
};
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Enable verbose debug messages");
#define dprintk if (debug) printk
/* Register values to initialise the demod, this will set VSB by default */
static struct init_tab {
u8 reg;
u16 data;
} init_tab[] = {
{ 0x00, 0x0071, },
{ 0x01, 0x3213, },
{ 0x09, 0x0025, },
{ 0x1c, 0x001d, },
{ 0x1f, 0x002d, },
{ 0x20, 0x001d, },
{ 0x22, 0x0022, },
{ 0x23, 0x0020, },
{ 0x29, 0x110f, },
{ 0x2a, 0x10b4, },
{ 0x2b, 0x10ae, },
{ 0x2c, 0x0031, },
{ 0x31, 0x010d, },
{ 0x32, 0x0100, },
{ 0x44, 0x0510, },
{ 0x54, 0x0104, },
{ 0x58, 0x2222, },
{ 0x59, 0x1162, },
{ 0x5a, 0x3211, },
{ 0x5d, 0x0370, },
{ 0x5e, 0x0296, },
{ 0x61, 0x0010, },
{ 0x63, 0x4a00, },
{ 0x65, 0x0800, },
{ 0x71, 0x0003, },
{ 0x72, 0x0470, },
{ 0x81, 0x0002, },
{ 0x82, 0x0600, },
{ 0x86, 0x0002, },
{ 0x8a, 0x2c38, },
{ 0x8b, 0x2a37, },
{ 0x92, 0x302f, },
{ 0x93, 0x3332, },
{ 0x96, 0x000c, },
{ 0x99, 0x0101, },
{ 0x9c, 0x2e37, },
{ 0x9d, 0x2c37, },
{ 0x9e, 0x2c37, },
{ 0xab, 0x0100, },
{ 0xac, 0x1003, },
{ 0xad, 0x103f, },
{ 0xe2, 0x0100, },
{ 0xe3, 0x1000, },
{ 0x28, 0x1010, },
{ 0xb1, 0x000e, },
};
/* VSB SNR lookup table */
static struct vsb_snr_tab {
u16 val;
u16 data;
} vsb_snr_tab[] = {
{ 924, 300, },
{ 923, 300, },
{ 918, 295, },
{ 915, 290, },
{ 911, 285, },
{ 906, 280, },
{ 901, 275, },
{ 896, 270, },
{ 891, 265, },
{ 885, 260, },
{ 879, 255, },
{ 873, 250, },
{ 864, 245, },
{ 858, 240, },
{ 850, 235, },
{ 841, 230, },
{ 832, 225, },
{ 823, 220, },
{ 812, 215, },
{ 802, 210, },
{ 788, 205, },
{ 778, 200, },
{ 767, 195, },
{ 753, 190, },
{ 740, 185, },
{ 725, 180, },
{ 707, 175, },
{ 689, 170, },
{ 671, 165, },
{ 656, 160, },
{ 637, 155, },
{ 616, 150, },
{ 542, 145, },
{ 519, 140, },
{ 507, 135, },
{ 497, 130, },
{ 492, 125, },
{ 474, 120, },
{ 300, 111, },
{ 0, 0, },
};
/* QAM64 SNR lookup table */
static struct