2014-03-25 06:56:00 +08:00
|
|
|
/*
|
|
|
|
* Support for LGDT3306A - 8VSB/QAM-B
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 Fred Richter <frichter@hauppauge.com>
|
|
|
|
* - driver structure based on lgdt3305.[ch] by Michael Krufky
|
|
|
|
* - code based on LG3306_V0.35 API by LG Electronics Inc.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
#include <asm/div64.h>
|
2017-09-03 20:19:31 +08:00
|
|
|
#include <linux/kernel.h>
|
2014-03-25 06:56:00 +08:00
|
|
|
#include <linux/dvb/frontend.h>
|
2017-12-29 02:03:51 +08:00
|
|
|
#include <media/dvb_math.h>
|
2014-03-25 06:56:00 +08:00
|
|
|
#include "lgdt3306a.h"
|
2017-01-10 11:14:18 +08:00
|
|
|
#include <linux/i2c-mux.h>
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
static int debug;
|
|
|
|
module_param(debug, int, 0644);
|
|
|
|
MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
|
|
|
|
|
|
|
|
#define DBG_INFO 1
|
|
|
|
#define DBG_REG 2
|
2014-07-28 06:24:24 +08:00
|
|
|
#define DBG_DUMP 4 /* FGR - comment out to remove dump code */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
#define lg_debug(fmt, arg...) \
|
|
|
|
printk(KERN_DEBUG pr_fmt(fmt), ## arg)
|
|
|
|
|
|
|
|
#define dbg_info(fmt, arg...) \
|
|
|
|
do { \
|
|
|
|
if (debug & DBG_INFO) \
|
|
|
|
lg_debug(fmt, ## arg); \
|
|
|
|
} while (0)
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
#define dbg_reg(fmt, arg...) \
|
|
|
|
do { \
|
|
|
|
if (debug & DBG_REG) \
|
|
|
|
lg_debug(fmt, ## arg); \
|
|
|
|
} while (0)
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
#define lg_chkerr(ret) \
|
|
|
|
({ \
|
|
|
|
int __ret; \
|
|
|
|
__ret = (ret < 0); \
|
|
|
|
if (__ret) \
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_err("error %d on line %d\n", ret, __LINE__); \
|
2014-03-25 06:56:00 +08:00
|
|
|
__ret; \
|
|
|
|
})
|
|
|
|
|
|
|
|
struct lgdt3306a_state {
|
|
|
|
struct i2c_adapter *i2c_adap;
|
|
|
|
const struct lgdt3306a_config *cfg;
|
|
|
|
|
|
|
|
struct dvb_frontend frontend;
|
|
|
|
|
2015-06-08 01:53:52 +08:00
|
|
|
enum fe_modulation current_modulation;
|
2014-03-25 06:56:00 +08:00
|
|
|
u32 current_frequency;
|
|
|
|
u32 snr;
|
2017-01-10 11:14:18 +08:00
|
|
|
|
|
|
|
struct i2c_mux_core *muxc;
|
2014-03-25 06:56:00 +08:00
|
|
|
};
|
|
|
|
|
2014-10-28 22:40:20 +08:00
|
|
|
/*
|
|
|
|
* LG3306A Register Usage
|
|
|
|
* (LG does not really name the registers, so this code does not either)
|
|
|
|
*
|
|
|
|
* 0000 -> 00FF Common control and status
|
|
|
|
* 1000 -> 10FF Synchronizer control and status
|
|
|
|
* 1F00 -> 1FFF Smart Antenna control and status
|
|
|
|
* 2100 -> 21FF VSB Equalizer control and status
|
|
|
|
* 2800 -> 28FF QAM Equalizer control and status
|
|
|
|
* 3000 -> 30FF FEC control and status
|
|
|
|
*/
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_lock_status {
|
|
|
|
LG3306_UNLOCK = 0x00,
|
|
|
|
LG3306_LOCK = 0x01,
|
2014-10-28 20:50:36 +08:00
|
|
|
LG3306_UNKNOWN_LOCK = 0xff
|
2014-08-04 02:29:04 +08:00
|
|
|
};
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_neverlock_status {
|
2014-03-25 06:56:00 +08:00
|
|
|
LG3306_NL_INIT = 0x00,
|
|
|
|
LG3306_NL_PROCESS = 0x01,
|
|
|
|
LG3306_NL_LOCK = 0x02,
|
|
|
|
LG3306_NL_FAIL = 0x03,
|
2014-10-28 20:50:36 +08:00
|
|
|
LG3306_NL_UNKNOWN = 0xff
|
2014-08-04 02:29:04 +08:00
|
|
|
};
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_modulation {
|
|
|
|
LG3306_VSB = 0x00,
|
|
|
|
LG3306_QAM64 = 0x01,
|
|
|
|
LG3306_QAM256 = 0x02,
|
2014-10-28 20:50:36 +08:00
|
|
|
LG3306_UNKNOWN_MODE = 0xff
|
2014-08-04 02:29:04 +08:00
|
|
|
};
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_lock_check {
|
2014-03-25 06:56:00 +08:00
|
|
|
LG3306_SYNC_LOCK,
|
|
|
|
LG3306_FEC_LOCK,
|
|
|
|
LG3306_TR_LOCK,
|
|
|
|
LG3306_AGC_LOCK,
|
2014-08-04 02:29:04 +08:00
|
|
|
};
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_DUMP
|
|
|
|
static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state);
|
|
|
|
static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
static int lgdt3306a_write_reg(struct lgdt3306a_state *state, u16 reg, u8 val)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u8 buf[] = { reg >> 8, reg & 0xff, val };
|
|
|
|
struct i2c_msg msg = {
|
|
|
|
.addr = state->cfg->i2c_addr, .flags = 0,
|
|
|
|
.buf = buf, .len = 3,
|
|
|
|
};
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = i2c_transfer(state->i2c_adap, &msg, 1);
|
|
|
|
|
|
|
|
if (ret != 1) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_err("error (addr %02x %02x <- %02x, err = %i)\n",
|
2014-03-25 06:56:00 +08:00
|
|
|
msg.buf[0], msg.buf[1], msg.buf[2], ret);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
else
|
|
|
|
return -EREMOTEIO;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_read_reg(struct lgdt3306a_state *state, u16 reg, u8 *val)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u8 reg_buf[] = { reg >> 8, reg & 0xff };
|
|
|
|
struct i2c_msg msg[] = {
|
|
|
|
{ .addr = state->cfg->i2c_addr,
|
|
|
|
.flags = 0, .buf = reg_buf, .len = 2 },
|
|
|
|
{ .addr = state->cfg->i2c_addr,
|
|
|
|
.flags = I2C_M_RD, .buf = val, .len = 1 },
|
|
|
|
};
|
|
|
|
|
|
|
|
ret = i2c_transfer(state->i2c_adap, msg, 2);
|
|
|
|
|
|
|
|
if (ret != 2) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_err("error (addr %02x reg %04x error (ret == %i)\n",
|
2014-03-25 06:56:00 +08:00
|
|
|
state->cfg->i2c_addr, reg, ret);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
else
|
|
|
|
return -EREMOTEIO;
|
|
|
|
}
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_reg("reg: 0x%04x, val: 0x%02x\n", reg, *val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define read_reg(state, reg) \
|
|
|
|
({ \
|
|
|
|
u8 __val; \
|
|
|
|
int ret = lgdt3306a_read_reg(state, reg, &__val); \
|
|
|
|
if (lg_chkerr(ret)) \
|
|
|
|
__val = 0; \
|
|
|
|
__val; \
|
|
|
|
})
|
|
|
|
|
|
|
|
static int lgdt3306a_set_reg_bit(struct lgdt3306a_state *state,
|
|
|
|
u16 reg, int bit, int onoff)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, reg, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
val &= ~(1 << bit);
|
|
|
|
val |= (onoff & 1) << bit;
|
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, reg, val);
|
|
|
|
lg_chkerr(ret);
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
static int lgdt3306a_soft_reset(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
msleep(20);
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1);
|
|
|
|
lg_chkerr(ret);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_mpeg_mode(struct lgdt3306a_state *state,
|
|
|
|
enum lgdt3306a_mpeg_mode mode)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", mode);
|
2014-10-28 22:35:18 +08:00
|
|
|
/* transport packet format - TPSENB=0x80 */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0071, 7,
|
|
|
|
mode == LGDT3306A_MPEG_PARALLEL ? 1 : 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/*
|
|
|
|
* start of packet signal duration
|
|
|
|
* TPSSOPBITEN=0x40; 0=byte duration, 1=bit duration
|
|
|
|
*/
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0071, 6, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0070, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x10; /* TPCLKSUPB=0x10 */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (mode == LGDT3306A_MPEG_PARALLEL)
|
2014-03-25 06:56:00 +08:00
|
|
|
val &= ~0x10;
|
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0070, val);
|
|
|
|
lg_chkerr(ret);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_mpeg_mode_polarity(struct lgdt3306a_state *state,
|
|
|
|
enum lgdt3306a_tp_clock_edge edge,
|
|
|
|
enum lgdt3306a_tp_valid_polarity valid)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("edge=%d, valid=%d\n", edge, valid);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0070, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
val &= ~0x06; /* TPCLKPOL=0x04, TPVALPOL=0x02 */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (edge == LGDT3306A_TPCLK_RISING_EDGE)
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x04;
|
2014-07-28 06:24:24 +08:00
|
|
|
if (valid == LGDT3306A_TP_VALID_HIGH)
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x02;
|
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0070, val);
|
|
|
|
lg_chkerr(ret);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_mpeg_tristate(struct lgdt3306a_state *state,
|
|
|
|
int mode)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", mode);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (mode) {
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0070, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 22:35:18 +08:00
|
|
|
/*
|
|
|
|
* Tristate bus; TPOUTEN=0x80, TPCLKOUTEN=0x20,
|
|
|
|
* TPDATAOUTEN=0x08
|
|
|
|
*/
|
|
|
|
val &= ~0xa8;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0070, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/* AGCIFOUTENB=0x40; 1=Disable IFAGC pin */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
} else {
|
2014-10-28 22:35:18 +08:00
|
|
|
/* enable IFAGC pin */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0003, 6, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0070, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
val |= 0xa8; /* enable bus */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0070, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
static int lgdt3306a_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("acquire=%d\n", acquire);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
return lgdt3306a_mpeg_tristate(state, acquire ? 0 : 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_power(struct lgdt3306a_state *state,
|
|
|
|
int mode)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", mode);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (mode == 0) {
|
2014-10-28 22:35:18 +08:00
|
|
|
/* into reset */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/* power down */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
} else {
|
2014-10-28 22:35:18 +08:00
|
|
|
/* out of reset */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 7, 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/* power up */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0000, 0, 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DBG_DUMP
|
|
|
|
lgdt3306a_DumpAllRegs(state);
|
|
|
|
#endif
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int lgdt3306a_set_vsb(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 0. Spectrum inversion detection manual; spectrum inverted */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0002, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf7; /* SPECINVAUTO Off */
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x04; /* SPECINV On */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0002, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0008, 0x80);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 2. Bandwidth mode for VSB(6MHz) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0009, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xe3;
|
|
|
|
val |= 0x0c; /* STDOPDETTMODE[2:0]=3 */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0009, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 3. QAM mode detection mode(None) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0009, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xfc; /* STDOPDETCMODE[1:0]=0 */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0009, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 4. ADC sampling frequency rate(2x sampling) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x000d, &val);
|
|
|
|
val &= 0xbf; /* SAMPLING4XFEN=0 */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x000d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
|
|
|
/* FGR - disable any AICC filtering, testing only */
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0024, 0x00);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ0 NT N-1(Video rejection) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002e, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002f, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0030, 0x00);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ1 NT N-1(Audio rejection) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002b, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002c, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002d, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ2 NT Co-Channel(Video rejection) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0028, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0029, 0x00);
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002a, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0025, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0026, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0027, 0x00);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
#else
|
|
|
|
/* FGR - this works well for HVR-1955,1975 */
|
|
|
|
|
|
|
|
/* 5. AICCOPMODE NT N-1 Adj. */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0024, 0x5A);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ0 NT N-1(Video rejection) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002e, 0x5A);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002f, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0030, 0x00);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ1 NT N-1(Audio rejection) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002b, 0x36);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002c, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x002d, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ2 NT Co-Channel(Video rejection) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0028, 0x2A);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0029, 0x00);
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x002a, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* AICCFIXFREQ3 NT Co-Channel(Audio rejection) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0025, 0x06);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0026, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0027, 0x00);
|
|
|
|
#endif
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x001e, &val);
|
|
|
|
val &= 0x0f;
|
|
|
|
val |= 0xa0;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x001e, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0022, 0x08);
|
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0023, 0xFF);
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x211f, &val);
|
|
|
|
val &= 0xef;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x211f, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2173, 0x01);
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x1061, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf8;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x04;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x1061, val);
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x103d, &val);
|
|
|
|
val &= 0xcf;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x103d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2122, 0x40);
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2141, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x3f;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x2141, val);
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2135, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x0f;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x70;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2135, val);
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0003, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf7;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0003, val);
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x001c, &val);
|
|
|
|
val &= 0x7f;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x001c, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 6. EQ step size */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2179, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf8;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x2179, val);
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x217a, &val);
|
|
|
|
val &= 0xf8;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x217a, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 7. Reset */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_soft_reset(state);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("complete\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_set_qam(struct lgdt3306a_state *state, int modulation)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("modulation=%d\n", modulation);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 1. Selection of standard mode(0x08=QAM, 0x80=VSB) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0008, 0x08);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 1a. Spectrum inversion detection to Auto */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0002, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xfb; /* SPECINV Off */
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x08; /* SPECINVAUTO On */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0002, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 2. Bandwidth mode for QAM */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0009, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xe3; /* STDOPDETTMODE[2:0]=0 VSB Off */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0009, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 3. : 64QAM/256QAM detection(manual, auto) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0009, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xfc;
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x02; /* STDOPDETCMODE[1:0]=1=Manual 2=Auto */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0009, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 3a. : 64QAM/256QAM selection for manual */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x101a, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf8;
|
2014-07-28 06:24:24 +08:00
|
|
|
if (modulation == QAM_64)
|
|
|
|
val |= 0x02; /* QMDQMODE[2:0]=2=QAM64 */
|
|
|
|
else
|
|
|
|
val |= 0x04; /* QMDQMODE[2:0]=4=QAM256 */
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x101a, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 4. ADC sampling frequency rate(4x sampling) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x000d, &val);
|
|
|
|
val &= 0xbf;
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x40; /* SAMPLING4XFEN=1 */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x000d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 5. No AICC operation in QAM mode */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0024, &val);
|
|
|
|
val &= 0x00;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0024, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2018-01-05 09:30:24 +08:00
|
|
|
/* 5.1 V0.36 SRDCHKALWAYS : For better QAM detection */
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x000a, &val);
|
|
|
|
val &= 0xfd;
|
|
|
|
val |= 0x02;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x000a, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* 5.2 V0.36 Control of "no signal" detector function */
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2849, &val);
|
|
|
|
val &= 0xdf;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2849, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
/* 5.3 Fix for Blonder Tongue HDE-2H-QAM and AQM modulators */
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x302b, &val);
|
|
|
|
val &= 0x7f; /* SELFSYNCFINDEN_CQS=0; disable auto reset */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x302b, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 6. Reset */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_soft_reset(state);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("complete\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_set_modulation(struct lgdt3306a_state *state,
|
|
|
|
struct dtv_frontend_properties *p)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
switch (p->modulation) {
|
|
|
|
case VSB_8:
|
|
|
|
ret = lgdt3306a_set_vsb(state);
|
|
|
|
break;
|
|
|
|
case QAM_64:
|
|
|
|
ret = lgdt3306a_set_qam(state, QAM_64);
|
|
|
|
break;
|
|
|
|
case QAM_256:
|
|
|
|
ret = lgdt3306a_set_qam(state, QAM_256);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
state->current_modulation = p->modulation;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
static int lgdt3306a_agc_setup(struct lgdt3306a_state *state,
|
|
|
|
struct dtv_frontend_properties *p)
|
|
|
|
{
|
2014-07-28 06:24:24 +08:00
|
|
|
/* TODO: anything we want to do here??? */
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
switch (p->modulation) {
|
|
|
|
case VSB_8:
|
|
|
|
break;
|
|
|
|
case QAM_64:
|
|
|
|
case QAM_256:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
static int lgdt3306a_set_inversion(struct lgdt3306a_state *state,
|
|
|
|
int inversion)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", inversion);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0002, 2, inversion ? 1 : 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_set_inversion_auto(struct lgdt3306a_state *state,
|
|
|
|
int enabled)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", enabled);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/* 0=Manual 1=Auto(QAM only) - SPECINVAUTO=0x04 */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0002, 3, enabled);
|
2014-03-25 06:56:00 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_spectral_inversion(struct lgdt3306a_state *state,
|
|
|
|
struct dtv_frontend_properties *p,
|
|
|
|
int inversion)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", inversion);
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 22:35:18 +08:00
|
|
|
/*
|
|
|
|
* FGR - spectral_inversion defaults already set for VSB and QAM;
|
|
|
|
* can enable later if desired
|
|
|
|
*/
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_set_inversion(state, inversion);
|
|
|
|
|
|
|
|
switch (p->modulation) {
|
|
|
|
case VSB_8:
|
2014-10-28 22:35:18 +08:00
|
|
|
/* Manual only for VSB */
|
|
|
|
ret = lgdt3306a_set_inversion_auto(state, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
break;
|
|
|
|
case QAM_64:
|
|
|
|
case QAM_256:
|
2014-10-28 22:35:18 +08:00
|
|
|
/* Auto ok for QAM */
|
|
|
|
ret = lgdt3306a_set_inversion_auto(state, 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_set_if(struct lgdt3306a_state *state,
|
|
|
|
struct dtv_frontend_properties *p)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
u16 if_freq_khz;
|
|
|
|
u8 nco1, nco2;
|
|
|
|
|
|
|
|
switch (p->modulation) {
|
|
|
|
case VSB_8:
|
|
|
|
if_freq_khz = state->cfg->vsb_if_khz;
|
|
|
|
break;
|
|
|
|
case QAM_64:
|
|
|
|
case QAM_256:
|
|
|
|
if_freq_khz = state->cfg->qam_if_khz;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
switch (if_freq_khz) {
|
2014-03-25 06:56:00 +08:00
|
|
|
default:
|
2016-09-01 19:09:41 +08:00
|
|
|
pr_warn("IF=%d KHz is not supported, 3250 assumed\n",
|
2014-10-28 22:35:18 +08:00
|
|
|
if_freq_khz);
|
2014-07-28 06:24:24 +08:00
|
|
|
/* fallthrough */
|
2014-10-25 22:26:15 +08:00
|
|
|
case 3250: /* 3.25Mhz */
|
2014-03-25 06:56:00 +08:00
|
|
|
nco1 = 0x34;
|
|
|
|
nco2 = 0x00;
|
|
|
|
break;
|
2014-10-25 22:26:15 +08:00
|
|
|
case 3500: /* 3.50Mhz */
|
2014-03-25 06:56:00 +08:00
|
|
|
nco1 = 0x38;
|
|
|
|
nco2 = 0x00;
|
|
|
|
break;
|
2014-10-25 22:26:15 +08:00
|
|
|
case 4000: /* 4.00Mhz */
|
2014-03-25 06:56:00 +08:00
|
|
|
nco1 = 0x40;
|
|
|
|
nco2 = 0x00;
|
|
|
|
break;
|
2014-10-25 22:26:15 +08:00
|
|
|
case 5000: /* 5.00Mhz */
|
2014-03-25 06:56:00 +08:00
|
|
|
nco1 = 0x50;
|
|
|
|
nco2 = 0x00;
|
|
|
|
break;
|
2014-07-28 06:24:24 +08:00
|
|
|
case 5380: /* 5.38Mhz */
|
2014-03-25 06:56:00 +08:00
|
|
|
nco1 = 0x56;
|
|
|
|
nco2 = 0x14;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0010, nco1);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x0011, nco2);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("if_freq=%d KHz->[%04x]\n", if_freq_khz, nco1<<8 | nco2);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
static int lgdt3306a_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (state->cfg->deny_i2c_rptr) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("deny_i2c_rptr=%d\n", state->cfg->deny_i2c_rptr);
|
2014-03-25 06:56:00 +08:00
|
|
|
return 0;
|
|
|
|
}
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d)\n", enable);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
/* NI2CRPTEN=0x80 */
|
|
|
|
return lgdt3306a_set_reg_bit(state, 0x0002, 7, enable ? 0 : 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_sleep(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
state->current_frequency = -1; /* force re-tune, when we wake */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
ret = lgdt3306a_mpeg_tristate(state, 1); /* disable data bus */
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
ret = lgdt3306a_power(state, 0); /* power down */
|
2014-03-25 06:56:00 +08:00
|
|
|
lg_chkerr(ret);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_fe_sleep(struct dvb_frontend *fe)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
|
|
|
return lgdt3306a_sleep(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_init(struct dvb_frontend *fe)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 1. Normal operation mode */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0001, 0, 1); /* SIMFASTENB=0x01 */
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 2. Spectrum inversion auto detection (Not valid for VSB) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_set_inversion_auto(state, 0);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 3. Spectrum inversion(According to the tuner configuration) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_set_inversion(state, 1);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 4. Peak-to-peak voltage of ADC input signal */
|
2014-10-28 22:35:18 +08:00
|
|
|
|
|
|
|
/* ADCSEL1V=0x80=1Vpp; 0x00=2Vpp */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0004, 7, 1);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 5. ADC output data capture clock phase */
|
2014-10-28 22:35:18 +08:00
|
|
|
|
|
|
|
/* 0=same phase as ADC clock */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0004, 2, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 5a. ADC sampling clock source */
|
2014-10-28 22:35:18 +08:00
|
|
|
|
|
|
|
/* ADCCLKPLLSEL=0x08; 0=use ext clock, not PLL */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0004, 3, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 6. Automatic PLL set */
|
2014-10-28 22:35:18 +08:00
|
|
|
|
|
|
|
/* PLLSETAUTO=0x40; 0=off */
|
|
|
|
ret = lgdt3306a_set_reg_bit(state, 0x0005, 6, 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (state->cfg->xtalMHz == 24) { /* 24MHz */
|
|
|
|
/* 7. Frequency for PLL output(0x2564 for 192MHz for 24MHz) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0005, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xc0;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x25;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0005, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0006, 0x64);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 8. ADC sampling frequency(0x180000 for 24MHz sampling) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x000d, &val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xc0;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x18;
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x000d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
} else if (state->cfg->xtalMHz == 25) { /* 25MHz */
|
|
|
|
/* 7. Frequency for PLL output */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0005, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xc0;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x25;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0005, val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0006, 0x64);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 8. ADC sampling frequency(0x190000 for 25MHz sampling) */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x000d, &val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xc0;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x19;
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x000d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
} else {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_err("Bad xtalMHz=%d\n", state->cfg->xtalMHz);
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x000e, 0x00);
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x000f, 0x00);
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 9. Center frequency of input signal of ADC */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0010, 0x34); /* 3.25MHz */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0011, 0x00);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 10. Fixed gain error value */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0014, 0); /* gain error=0 */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 10a. VSB TR BW gear shift initial step */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x103c, &val);
|
|
|
|
val &= 0x0f;
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x20; /* SAMGSAUTOSTL_V[3:0] = 2 */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x103c, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 10b. Timing offset calibration in low temperature for VSB */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x103d, &val);
|
|
|
|
val &= 0xfc;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x03;
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x103d, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 10c. Timing offset calibration in low temperature for QAM */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x1036, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf0;
|
|
|
|
val |= 0x0c;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x1036, val);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 11. Using the imaginary part of CIR in CIR loading */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x211f, &val);
|
|
|
|
val &= 0xef; /* do not use imaginary of CIR */
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x211f, val);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 12. Control of no signal detector function */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2849, &val);
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xef; /* NOUSENOSIGDET=0, enable no signal detector */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x2849, val);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* FGR - put demod in some known mode */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_set_vsb(state);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 13. TP stream format */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 14. disable output buses */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_mpeg_tristate(state, 1);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* 15. Sleep (in reset) */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_sleep(state);
|
|
|
|
lg_chkerr(ret);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_set_parameters(struct dvb_frontend *fe)
|
|
|
|
{
|
|
|
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
int ret;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d, %d)\n", p->frequency, p->modulation);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (state->current_frequency == p->frequency &&
|
|
|
|
state->current_modulation == p->modulation) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info(" (already set, skipping ...)\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
state->current_frequency = -1;
|
|
|
|
state->current_modulation = -1;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
ret = lgdt3306a_power(state, 1); /* power up */
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
if (fe->ops.tuner_ops.set_params) {
|
|
|
|
ret = fe->ops.tuner_ops.set_params(fe);
|
|
|
|
if (fe->ops.i2c_gate_ctrl)
|
|
|
|
fe->ops.i2c_gate_ctrl(fe, 0);
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
state->current_frequency = p->frequency;
|
|
|
|
#endif
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = lgdt3306a_set_modulation(state, p);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_agc_setup(state, p);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_set_if(state, p);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_spectral_inversion(state, p,
|
2014-10-28 22:35:18 +08:00
|
|
|
state->cfg->spectral_inversion ? 1 : 0);
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_mpeg_mode(state, state->cfg->mpeg_mode);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_mpeg_mode_polarity(state,
|
|
|
|
state->cfg->tpclk_edge,
|
|
|
|
state->cfg->tpvalid_polarity);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
ret = lgdt3306a_mpeg_tristate(state, 0); /* enable data bus */
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = lgdt3306a_soft_reset(state);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
#ifdef DBG_DUMP
|
|
|
|
lgdt3306a_DumpAllRegs(state);
|
|
|
|
#endif
|
|
|
|
state->current_frequency = p->frequency;
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-02-04 22:58:30 +08:00
|
|
|
static int lgdt3306a_get_frontend(struct dvb_frontend *fe,
|
|
|
|
struct dtv_frontend_properties *p)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
dbg_info("(%u, %d)\n",
|
|
|
|
state->current_frequency, state->current_modulation);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
p->modulation = state->current_modulation;
|
|
|
|
p->frequency = state->current_frequency;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static enum dvbfe_algo lgdt3306a_get_frontend_algo(struct dvb_frontend *fe)
|
|
|
|
{
|
|
|
|
#if 1
|
|
|
|
return DVBFE_ALGO_CUSTOM;
|
|
|
|
#else
|
|
|
|
return DVBFE_ALGO_HW;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
2014-10-28 21:21:48 +08:00
|
|
|
static int lgdt3306a_monitor_vsb(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
u8 snrRef, maxPowerMan, nCombDet;
|
|
|
|
u16 fbDlyCir;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x21a1, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
snrRef = val & 0x3f;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2185, &maxPowerMan);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2191, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
nCombDet = (val & 0x80) >> 7;
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2180, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
fbDlyCir = (val & 0x03) << 8;
|
2014-10-28 21:21:48 +08:00
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2181, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
fbDlyCir |= val;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("snrRef=%d maxPowerMan=0x%x nCombDet=%d fbDlyCir=0x%x\n",
|
2014-03-25 06:56:00 +08:00
|
|
|
snrRef, maxPowerMan, nCombDet, fbDlyCir);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* Carrier offset sub loop bandwidth */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x1061, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xf8;
|
2014-10-28 22:35:18 +08:00
|
|
|
if ((snrRef > 18) && (maxPowerMan > 0x68)
|
|
|
|
&& (nCombDet == 0x01)
|
|
|
|
&& ((fbDlyCir == 0x03FF) || (fbDlyCir < 0x6C))) {
|
2014-07-28 06:24:24 +08:00
|
|
|
/* SNR is over 18dB and no ghosting */
|
|
|
|
val |= 0x00; /* final bandwidth = 0 */
|
2014-03-25 06:56:00 +08:00
|
|
|
} else {
|
2014-07-28 06:24:24 +08:00
|
|
|
val |= 0x04; /* final bandwidth = 4 */
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x1061, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* Adjust Notch Filter */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0024, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x0f;
|
2014-07-28 06:24:24 +08:00
|
|
|
if (nCombDet == 0) { /* Turn on the Notch Filter */
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x50;
|
|
|
|
}
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x0024, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* VSB Timing Recovery output normalization */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x103d, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0xcf;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x20;
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x103d, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_modulation
|
|
|
|
lgdt3306a_check_oper_mode(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
u8 val = 0;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0081, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
goto err;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if (val & 0x80) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("VSB\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_VSB;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-08-04 01:51:49 +08:00
|
|
|
if (val & 0x08) {
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x00a6, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
goto err;
|
2014-03-25 06:56:00 +08:00
|
|
|
val = val >> 2;
|
|
|
|
if (val & 0x01) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("QAM256\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_QAM256;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 22:05:35 +08:00
|
|
|
dbg_info("QAM64\n");
|
|
|
|
return LG3306_QAM64;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 21:21:48 +08:00
|
|
|
err:
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("UNKNOWN\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNKNOWN_MODE;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_lock_status
|
|
|
|
lgdt3306a_check_lock_status(struct lgdt3306a_state *state,
|
|
|
|
enum lgdt3306a_lock_check whatLock)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
u8 val = 0;
|
|
|
|
int ret;
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_modulation modeOper;
|
|
|
|
enum lgdt3306a_lock_status lockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
modeOper = LG3306_UNKNOWN_MODE;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
switch (whatLock) {
|
|
|
|
case LG3306_SYNC_LOCK:
|
|
|
|
{
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x00a6, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
|
|
|
|
if ((val & 0x80) == 0x80)
|
|
|
|
lockStatus = LG3306_LOCK;
|
|
|
|
else
|
|
|
|
lockStatus = LG3306_UNLOCK;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("SYNC_LOCK=%x\n", lockStatus);
|
2014-07-28 06:24:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LG3306_AGC_LOCK:
|
|
|
|
{
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0080, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
|
|
|
|
if ((val & 0x40) == 0x40)
|
|
|
|
lockStatus = LG3306_LOCK;
|
|
|
|
else
|
|
|
|
lockStatus = LG3306_UNLOCK;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("AGC_LOCK=%x\n", lockStatus);
|
2014-07-28 06:24:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LG3306_TR_LOCK:
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-07-28 06:24:24 +08:00
|
|
|
modeOper = lgdt3306a_check_oper_mode(state);
|
|
|
|
if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) {
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x1094, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if ((val & 0x80) == 0x80)
|
|
|
|
lockStatus = LG3306_LOCK;
|
|
|
|
else
|
|
|
|
lockStatus = LG3306_UNLOCK;
|
2014-07-28 06:24:24 +08:00
|
|
|
} else
|
|
|
|
lockStatus = LG3306_UNKNOWN_LOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("TR_LOCK=%x\n", lockStatus);
|
2014-07-28 06:24:24 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LG3306_FEC_LOCK:
|
|
|
|
{
|
|
|
|
modeOper = lgdt3306a_check_oper_mode(state);
|
|
|
|
if ((modeOper == LG3306_QAM64) || (modeOper == LG3306_QAM256)) {
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0080, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if ((val & 0x10) == 0x10)
|
2014-03-25 06:56:00 +08:00
|
|
|
lockStatus = LG3306_LOCK;
|
|
|
|
else
|
|
|
|
lockStatus = LG3306_UNLOCK;
|
2014-07-28 06:24:24 +08:00
|
|
|
} else
|
|
|
|
lockStatus = LG3306_UNKNOWN_LOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("FEC_LOCK=%x\n", lockStatus);
|
2014-07-28 06:24:24 +08:00
|
|
|
break;
|
|
|
|
}
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
default:
|
|
|
|
lockStatus = LG3306_UNKNOWN_LOCK;
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("UNKNOWN whatLock=%d\n", whatLock);
|
2014-07-28 06:24:24 +08:00
|
|
|
break;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
return lockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_neverlock_status
|
|
|
|
lgdt3306a_check_neverlock_status(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
u8 val = 0;
|
|
|
|
int ret;
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_neverlock_status lockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0080, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-08-04 02:29:04 +08:00
|
|
|
lockStatus = (enum lgdt3306a_neverlock_status)(val & 0x03);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("NeverLock=%d", lockStatus);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
return lockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 21:21:48 +08:00
|
|
|
static int lgdt3306a_pre_monitoring(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
u8 val = 0;
|
|
|
|
int ret;
|
|
|
|
u8 currChDiffACQ, snrRef, mainStrong, aiccrejStatus;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* Channel variation */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x21bc, &currChDiffACQ);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* SNR of Frame sync */
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x21a1, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
snrRef = val & 0x3f;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* Strong Main CIR */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2199, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
mainStrong = (val & 0x40) >> 6;
|
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0090, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
aiccrejStatus = (val & 0xf0) >> 4;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("snrRef=%d mainStrong=%d aiccrejStatus=%d currChDiffACQ=0x%x\n",
|
2014-03-25 06:56:00 +08:00
|
|
|
snrRef, mainStrong, aiccrejStatus, currChDiffACQ);
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 22:35:18 +08:00
|
|
|
/* Dynamic ghost exists */
|
|
|
|
if ((mainStrong == 0) && (currChDiffACQ > 0x70))
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif
|
|
|
|
if (mainStrong == 0) {
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2135, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x0f;
|
|
|
|
val |= 0xa0;
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_write_reg(state, 0x2135, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2141, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x3f;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x80;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2141, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2122, 0x70);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
} else { /* Weak ghost or static channel */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x2135, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x0f;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x70;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2135, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x2141, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-10-28 20:50:36 +08:00
|
|
|
val &= 0x3f;
|
2014-03-25 06:56:00 +08:00
|
|
|
val |= 0x40;
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2141, val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
ret = lgdt3306a_write_reg(state, 0x2122, 0x40);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 21:21:48 +08:00
|
|
|
return 0;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_lock_status
|
|
|
|
lgdt3306a_sync_lock_poll(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_lock_status syncLockStatus = LG3306_UNLOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
msleep(30);
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
syncLockStatus = lgdt3306a_check_lock_status(state,
|
|
|
|
LG3306_SYNC_LOCK);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if (syncLockStatus == LG3306_LOCK) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("locked(%d)\n", i);
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_LOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
}
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("not locked\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNLOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_lock_status
|
|
|
|
lgdt3306a_fec_lock_poll(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_lock_status FECLockStatus = LG3306_UNLOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
msleep(30);
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
FECLockStatus = lgdt3306a_check_lock_status(state,
|
|
|
|
LG3306_FEC_LOCK);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if (FECLockStatus == LG3306_LOCK) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("locked(%d)\n", i);
|
2014-07-28 06:24:24 +08:00
|
|
|
return FECLockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
}
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("not locked\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return FECLockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_neverlock_status
|
|
|
|
lgdt3306a_neverlock_poll(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-08-04 02:29:04 +08:00
|
|
|
enum lgdt3306a_neverlock_status NLLockStatus = LG3306_NL_FAIL;
|
2014-03-25 06:56:00 +08:00
|
|
|
int i;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
for (i = 0; i < 5; i++) {
|
2014-03-25 06:56:00 +08:00
|
|
|
msleep(30);
|
|
|
|
|
|
|
|
NLLockStatus = lgdt3306a_check_neverlock_status(state);
|
|
|
|
|
|
|
|
if (NLLockStatus == LG3306_NL_LOCK) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("NL_LOCK(%d)\n", i);
|
2014-07-28 06:24:24 +08:00
|
|
|
return NLLockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
}
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("NLLockStatus=%d\n", NLLockStatus);
|
2014-07-28 06:24:24 +08:00
|
|
|
return NLLockStatus;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static u8 lgdt3306a_get_packet_error(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
u8 val;
|
|
|
|
int ret;
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x00fa, &val);
|
2014-10-28 21:21:48 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
return val;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:30:44 +08:00
|
|
|
static const u32 valx_x10[] = {
|
|
|
|
10, 11, 13, 15, 17, 20, 25, 33, 41, 50, 59, 73, 87, 100
|
|
|
|
};
|
|
|
|
static const u32 log10x_x1000[] = {
|
2014-10-28 22:40:20 +08:00
|
|
|
0, 41, 114, 176, 230, 301, 398, 518, 613, 699, 771, 863, 939, 1000
|
2014-10-28 22:30:44 +08:00
|
|
|
};
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
static u32 log10_x1000(u32 x)
|
|
|
|
{
|
2014-10-28 21:07:03 +08:00
|
|
|
u32 diff_val, step_val, step_log10;
|
2014-03-25 06:56:00 +08:00
|
|
|
u32 log_val = 0;
|
2014-07-28 06:24:24 +08:00
|
|
|
u32 i;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (x <= 0)
|
|
|
|
return -1000000; /* signal error */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:05:35 +08:00
|
|
|
if (x == 10)
|
|
|
|
return 0; /* log(1)=0 */
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (x < 10) {
|
|
|
|
while (x < 10) {
|
|
|
|
x = x * 10;
|
2014-03-25 06:56:00 +08:00
|
|
|
log_val--;
|
|
|
|
}
|
2014-10-28 22:05:35 +08:00
|
|
|
} else { /* x > 10 */
|
2014-07-28 06:24:24 +08:00
|
|
|
while (x >= 100) {
|
|
|
|
x = x / 10;
|
2014-03-25 06:56:00 +08:00
|
|
|
log_val++;
|
|
|
|
}
|
2014-07-28 06:24:24 +08:00
|
|
|
}
|
2014-03-25 06:56:00 +08:00
|
|
|
log_val *= 1000;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (x == 10) /* was our input an exact multiple of 10 */
|
|
|
|
return log_val; /* don't need to interpolate */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
/* find our place on the log curve */
|
2014-10-28 22:30:44 +08:00
|
|
|
for (i = 1; i < ARRAY_SIZE(valx_x10); i++) {
|
2014-07-28 06:24:24 +08:00
|
|
|
if (valx_x10[i] >= x)
|
|
|
|
break;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 22:30:44 +08:00
|
|
|
if (i == ARRAY_SIZE(valx_x10))
|
2014-10-28 21:07:03 +08:00
|
|
|
return log_val + log10x_x1000[i - 1];
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 21:07:03 +08:00
|
|
|
diff_val = x - valx_x10[i-1];
|
|
|
|
step_val = valx_x10[i] - valx_x10[i - 1];
|
|
|
|
step_log10 = log10x_x1000[i] - log10x_x1000[i - 1];
|
|
|
|
|
|
|
|
/* do a linear interpolation to get in-between values */
|
|
|
|
return log_val + log10x_x1000[i - 1] +
|
|
|
|
((diff_val*step_log10) / step_val);
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static u32 lgdt3306a_calculate_snr_x100(struct lgdt3306a_state *state)
|
|
|
|
{
|
2014-10-25 22:26:15 +08:00
|
|
|
u32 mse; /* Mean-Square Error */
|
|
|
|
u32 pwr; /* Constelation power */
|
2014-03-25 06:56:00 +08:00
|
|
|
u32 snr_x100;
|
|
|
|
|
2014-10-28 20:50:36 +08:00
|
|
|
mse = (read_reg(state, 0x00ec) << 8) |
|
|
|
|
(read_reg(state, 0x00ed));
|
|
|
|
pwr = (read_reg(state, 0x00e8) << 8) |
|
|
|
|
(read_reg(state, 0x00e9));
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if (mse == 0) /* no signal */
|
|
|
|
return 0;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
snr_x100 = log10_x1000((pwr * 10000) / mse) - 3000;
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("mse=%u, pwr=%u, snr_x100=%d\n", mse, pwr, snr_x100);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
return snr_x100;
|
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_lock_status
|
|
|
|
lgdt3306a_vsb_lock_poll(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-10-28 21:27:34 +08:00
|
|
|
int ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
u8 cnt = 0;
|
|
|
|
u8 packet_error;
|
|
|
|
u32 snr;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
for (cnt = 0; cnt < 10; cnt++) {
|
2014-03-25 06:56:00 +08:00
|
|
|
if (lgdt3306a_sync_lock_poll(state) == LG3306_UNLOCK) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("no sync lock!\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNLOCK;
|
2014-10-28 22:00:48 +08:00
|
|
|
}
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
msleep(20);
|
|
|
|
ret = lgdt3306a_pre_monitoring(state);
|
|
|
|
if (ret)
|
|
|
|
break;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
packet_error = lgdt3306a_get_packet_error(state);
|
|
|
|
snr = lgdt3306a_calculate_snr_x100(state);
|
|
|
|
dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
if ((snr >= 1500) && (packet_error < 0xff))
|
|
|
|
return LG3306_LOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 22:00:48 +08:00
|
|
|
|
|
|
|
dbg_info("not locked!\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNLOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static enum lgdt3306a_lock_status
|
|
|
|
lgdt3306a_qam_lock_poll(struct lgdt3306a_state *state)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
2014-10-28 22:00:48 +08:00
|
|
|
u8 cnt;
|
2014-03-25 06:56:00 +08:00
|
|
|
u8 packet_error;
|
|
|
|
u32 snr;
|
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
for (cnt = 0; cnt < 10; cnt++) {
|
2014-07-28 06:24:24 +08:00
|
|
|
if (lgdt3306a_fec_lock_poll(state) == LG3306_UNLOCK) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("no fec lock!\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNLOCK;
|
2014-10-28 22:00:48 +08:00
|
|
|
}
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
msleep(20);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
packet_error = lgdt3306a_get_packet_error(state);
|
|
|
|
snr = lgdt3306a_calculate_snr_x100(state);
|
|
|
|
dbg_info("cnt=%d errors=%d snr=%d\n", cnt, packet_error, snr);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-10-28 22:00:48 +08:00
|
|
|
if ((snr >= 1500) && (packet_error < 0xff))
|
|
|
|
return LG3306_LOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
2014-10-28 22:00:48 +08:00
|
|
|
|
|
|
|
dbg_info("not locked!\n");
|
2014-07-28 06:24:24 +08:00
|
|
|
return LG3306_UNLOCK;
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
2015-06-08 01:53:52 +08:00
|
|
|
static int lgdt3306a_read_status(struct dvb_frontend *fe,
|
|
|
|
enum fe_status *status)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
u16 strength = 0;
|
2014-07-28 06:24:24 +08:00
|
|
|
int ret = 0;
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
if (fe->ops.tuner_ops.get_rf_strength) {
|
|
|
|
ret = fe->ops.tuner_ops.get_rf_strength(fe, &strength);
|
2014-10-28 22:07:52 +08:00
|
|
|
if (ret == 0)
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("strength=%d\n", strength);
|
2014-10-28 22:07:52 +08:00
|
|
|
else
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("fe->ops.tuner_ops.get_rf_strength() failed\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
*status = 0;
|
2014-07-28 06:24:24 +08:00
|
|
|
if (lgdt3306a_neverlock_poll(state) == LG3306_NL_LOCK) {
|
2014-03-25 06:56:00 +08:00
|
|
|
*status |= FE_HAS_SIGNAL;
|
|
|
|
*status |= FE_HAS_CARRIER;
|
|
|
|
|
|
|
|
switch (state->current_modulation) {
|
|
|
|
case QAM_256:
|
|
|
|
case QAM_64:
|
2014-07-28 06:24:24 +08:00
|
|
|
if (lgdt3306a_qam_lock_poll(state) == LG3306_LOCK) {
|
2014-03-25 06:56:00 +08:00
|
|
|
*status |= FE_HAS_VITERBI;
|
|
|
|
*status |= FE_HAS_SYNC;
|
|
|
|
|
|
|
|
*status |= FE_HAS_LOCK;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case VSB_8:
|
2014-07-28 06:24:24 +08:00
|
|
|
if (lgdt3306a_vsb_lock_poll(state) == LG3306_LOCK) {
|
2014-03-25 06:56:00 +08:00
|
|
|
*status |= FE_HAS_VITERBI;
|
|
|
|
*status |= FE_HAS_SYNC;
|
|
|
|
|
|
|
|
*status |= FE_HAS_LOCK;
|
|
|
|
|
2014-10-28 21:21:48 +08:00
|
|
|
ret = lgdt3306a_monitor_vsb(state);
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int lgdt3306a_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
|
|
|
state->snr = lgdt3306a_calculate_snr_x100(state);
|
|
|
|
/* report SNR in dB * 10 */
|
|
|
|
*snr = state->snr/10;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_read_signal_strength(struct dvb_frontend *fe,
|
|
|
|
u16 *strength)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Calculate some sort of "strength" from SNR
|
|
|
|
*/
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
2014-10-25 22:26:15 +08:00
|
|
|
u16 snr; /* snr_x10 */
|
2014-03-25 06:56:00 +08:00
|
|
|
int ret;
|
2014-07-28 06:24:24 +08:00
|
|
|
u32 ref_snr; /* snr*100 */
|
2014-03-25 06:56:00 +08:00
|
|
|
u32 str;
|
|
|
|
|
|
|
|
*strength = 0;
|
|
|
|
|
|
|
|
switch (state->current_modulation) {
|
|
|
|
case VSB_8:
|
2014-07-28 06:24:24 +08:00
|
|
|
ref_snr = 1600; /* 16dB */
|
2014-03-25 06:56:00 +08:00
|
|
|
break;
|
|
|
|
case QAM_64:
|
2014-07-28 06:24:24 +08:00
|
|
|
ref_snr = 2200; /* 22dB */
|
2014-03-25 06:56:00 +08:00
|
|
|
break;
|
|
|
|
case QAM_256:
|
2014-07-28 06:24:24 +08:00
|
|
|
ref_snr = 2800; /* 28dB */
|
2014-03-25 06:56:00 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = fe->ops.read_snr(fe, &snr);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
if (state->snr <= (ref_snr - 100))
|
2014-03-25 06:56:00 +08:00
|
|
|
str = 0;
|
2014-07-28 06:24:24 +08:00
|
|
|
else if (state->snr <= ref_snr)
|
|
|
|
str = (0xffff * 65) / 100; /* 65% */
|
2014-03-25 06:56:00 +08:00
|
|
|
else {
|
|
|
|
str = state->snr - ref_snr;
|
|
|
|
str /= 50;
|
2014-07-28 06:24:24 +08:00
|
|
|
str += 78; /* 78%-100% */
|
|
|
|
if (str > 100)
|
2014-03-25 06:56:00 +08:00
|
|
|
str = 100;
|
|
|
|
str = (0xffff * str) / 100;
|
|
|
|
}
|
|
|
|
*strength = (u16)str;
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("strength=%u\n", *strength);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
fail:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
static int lgdt3306a_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
u32 tmp;
|
|
|
|
|
|
|
|
*ber = 0;
|
|
|
|
#if 1
|
2014-10-28 22:35:18 +08:00
|
|
|
/* FGR - FIXME - I don't know what value is expected by dvb_core
|
2014-07-28 06:24:24 +08:00
|
|
|
* what is the scale of the value?? */
|
2014-10-28 20:50:36 +08:00
|
|
|
tmp = read_reg(state, 0x00fc); /* NBERVALUE[24-31] */
|
|
|
|
tmp = (tmp << 8) | read_reg(state, 0x00fd); /* NBERVALUE[16-23] */
|
|
|
|
tmp = (tmp << 8) | read_reg(state, 0x00fe); /* NBERVALUE[8-15] */
|
|
|
|
tmp = (tmp << 8) | read_reg(state, 0x00ff); /* NBERVALUE[0-7] */
|
2014-03-25 06:56:00 +08:00
|
|
|
*ber = tmp;
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("ber=%u\n", tmp);
|
2014-03-25 06:56:00 +08:00
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
*ucblocks = 0;
|
2014-03-25 06:56:00 +08:00
|
|
|
#if 1
|
2014-10-28 22:35:18 +08:00
|
|
|
/* FGR - FIXME - I don't know what value is expected by dvb_core
|
2014-07-28 06:24:24 +08:00
|
|
|
* what happens when value wraps? */
|
2014-10-28 20:50:36 +08:00
|
|
|
*ucblocks = read_reg(state, 0x00f4); /* TPIFTPERRCNT[0-7] */
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("ucblocks=%u\n", *ucblocks);
|
2014-03-25 06:56:00 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-28 22:35:18 +08:00
|
|
|
static int lgdt3306a_tune(struct dvb_frontend *fe, bool re_tune,
|
|
|
|
unsigned int mode_flags, unsigned int *delay,
|
2015-06-08 01:53:52 +08:00
|
|
|
enum fe_status *status)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("re_tune=%u\n", re_tune);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
if (re_tune) {
|
2014-07-28 06:24:24 +08:00
|
|
|
state->current_frequency = -1; /* force re-tune */
|
2014-08-04 02:18:23 +08:00
|
|
|
ret = lgdt3306a_set_parameters(fe);
|
|
|
|
if (ret != 0)
|
2014-03-25 06:56:00 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
*delay = 125;
|
|
|
|
ret = lgdt3306a_read_status(fe, status);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_get_tune_settings(struct dvb_frontend *fe,
|
2014-07-28 06:24:24 +08:00
|
|
|
struct dvb_frontend_tune_settings
|
|
|
|
*fe_tune_settings)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
fe_tune_settings->min_delay_ms = 100;
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_search(struct dvb_frontend *fe)
|
|
|
|
{
|
2015-06-08 01:53:52 +08:00
|
|
|
enum fe_status status = 0;
|
2016-07-26 02:38:59 +08:00
|
|
|
int ret;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
/* set frontend */
|
|
|
|
ret = lgdt3306a_set_parameters(fe);
|
|
|
|
if (ret)
|
|
|
|
goto error;
|
|
|
|
|
2016-07-26 02:38:59 +08:00
|
|
|
ret = lgdt3306a_read_status(fe, &status);
|
|
|
|
if (ret)
|
|
|
|
goto error;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
/* check if we have a valid signal */
|
2014-07-28 06:24:24 +08:00
|
|
|
if (status & FE_HAS_LOCK)
|
2014-03-25 06:56:00 +08:00
|
|
|
return DVBFE_ALGO_SEARCH_SUCCESS;
|
2014-07-28 06:24:24 +08:00
|
|
|
else
|
2014-03-25 06:56:00 +08:00
|
|
|
return DVBFE_ALGO_SEARCH_AGAIN;
|
|
|
|
|
|
|
|
error:
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("failed (%d)\n", ret);
|
2014-03-25 06:56:00 +08:00
|
|
|
return DVBFE_ALGO_SEARCH_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lgdt3306a_release(struct dvb_frontend *fe)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = fe->demodulator_priv;
|
2014-07-28 06:24:24 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
kfree(state);
|
|
|
|
}
|
|
|
|
|
2016-08-10 05:32:21 +08:00
|
|
|
static const struct dvb_frontend_ops lgdt3306a_ops;
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config,
|
2014-10-28 20:56:10 +08:00
|
|
|
struct i2c_adapter *i2c_adap)
|
2014-03-25 06:56:00 +08:00
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = NULL;
|
|
|
|
int ret;
|
|
|
|
u8 val;
|
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
dbg_info("(%d-%04x)\n",
|
2014-03-25 06:56:00 +08:00
|
|
|
i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
|
|
|
|
config ? config->i2c_addr : 0);
|
|
|
|
|
|
|
|
state = kzalloc(sizeof(struct lgdt3306a_state), GFP_KERNEL);
|
|
|
|
if (state == NULL)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
state->cfg = config;
|
|
|
|
state->i2c_adap = i2c_adap;
|
|
|
|
|
|
|
|
memcpy(&state->frontend.ops, &lgdt3306a_ops,
|
|
|
|
sizeof(struct dvb_frontend_ops));
|
|
|
|
state->frontend.demodulator_priv = state;
|
|
|
|
|
|
|
|
/* verify that we're talking to a lg3306a */
|
2014-07-28 06:24:24 +08:00
|
|
|
/* FGR - NOTE - there is no obvious ChipId to check; we check
|
|
|
|
* some "known" bits after reset, but it's still just a guess */
|
2014-03-25 06:56:00 +08:00
|
|
|
ret = lgdt3306a_read_reg(state, 0x0000, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-07-28 06:24:24 +08:00
|
|
|
if ((val & 0x74) != 0x74) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("expected 0x74, got 0x%x\n", (val & 0x74));
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 22:35:18 +08:00
|
|
|
/* FIXME - re-enable when we know this is right */
|
|
|
|
goto fail;
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0001, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-10-28 20:50:36 +08:00
|
|
|
if ((val & 0xf6) != 0xc6) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("expected 0xc6, got 0x%x\n", (val & 0xf6));
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 22:35:18 +08:00
|
|
|
/* FIXME - re-enable when we know this is right */
|
|
|
|
goto fail;
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
ret = lgdt3306a_read_reg(state, 0x0002, &val);
|
|
|
|
if (lg_chkerr(ret))
|
|
|
|
goto fail;
|
2014-07-28 06:24:24 +08:00
|
|
|
if ((val & 0x73) != 0x03) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("expected 0x03, got 0x%x\n", (val & 0x73));
|
2014-07-28 06:24:24 +08:00
|
|
|
#if 0
|
2014-10-28 22:35:18 +08:00
|
|
|
/* FIXME - re-enable when we know this is right */
|
|
|
|
goto fail;
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
state->current_frequency = -1;
|
|
|
|
state->current_modulation = -1;
|
|
|
|
|
|
|
|
lgdt3306a_sleep(state);
|
|
|
|
|
|
|
|
return &state->frontend;
|
|
|
|
|
|
|
|
fail:
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
pr_warn("unable to detect LGDT3306A hardware\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
kfree(state);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-08-04 02:05:59 +08:00
|
|
|
EXPORT_SYMBOL(lgdt3306a_attach);
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
#ifdef DBG_DUMP
|
|
|
|
|
|
|
|
static const short regtab[] = {
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0000, /* SOFTRSTB 1'b1 1'b1 1'b1 ADCPDB 1'b1 PLLPDB GBBPDB 11111111 */
|
|
|
|
0x0001, /* 1'b1 1'b1 1'b0 1'b0 AUTORPTRS */
|
|
|
|
0x0002, /* NI2CRPTEN 1'b0 1'b0 1'b0 SPECINVAUT */
|
|
|
|
0x0003, /* AGCRFOUT */
|
|
|
|
0x0004, /* ADCSEL1V ADCCNT ADCCNF ADCCNS ADCCLKPLL */
|
|
|
|
0x0005, /* PLLINDIVSE */
|
|
|
|
0x0006, /* PLLCTRL[7:0] 11100001 */
|
|
|
|
0x0007, /* SYSINITWAITTIME[7:0] (msec) 00001000 */
|
|
|
|
0x0008, /* STDOPMODE[7:0] 10000000 */
|
|
|
|
0x0009, /* 1'b0 1'b0 1'b0 STDOPDETTMODE[2:0] STDOPDETCMODE[1:0] 00011110 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x000a, /* DAFTEN 1'b1 x x SCSYSLOCK */
|
|
|
|
0x000b, /* SCSYSLOCKCHKTIME[7:0] (10msec) 01100100 */
|
|
|
|
0x000d, /* x SAMPLING4 */
|
|
|
|
0x000e, /* SAMFREQ[15:8] 00000000 */
|
|
|
|
0x000f, /* SAMFREQ[7:0] 00000000 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0010, /* IFFREQ[15:8] 01100000 */
|
|
|
|
0x0011, /* IFFREQ[7:0] 00000000 */
|
|
|
|
0x0012, /* AGCEN AGCREFMO */
|
|
|
|
0x0013, /* AGCRFFIXB AGCIFFIXB AGCLOCKDETRNGSEL[1:0] 1'b1 1'b0 1'b0 1'b0 11101000 */
|
|
|
|
0x0014, /* AGCFIXVALUE[7:0] 01111111 */
|
|
|
|
0x0015, /* AGCREF[15:8] 00001010 */
|
|
|
|
0x0016, /* AGCREF[7:0] 11100100 */
|
|
|
|
0x0017, /* AGCDELAY[7:0] 00100000 */
|
|
|
|
0x0018, /* AGCRFBW[3:0] AGCIFBW[3:0] 10001000 */
|
|
|
|
0x0019, /* AGCUDOUTMODE[1:0] AGCUDCTRLLEN[1:0] AGCUDCTRL */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x001c, /* 1'b1 PFEN MFEN AICCVSYNC */
|
|
|
|
0x001d, /* 1'b0 1'b1 1'b0 1'b1 AICCVSYNC */
|
|
|
|
0x001e, /* AICCALPHA[3:0] 1'b1 1'b0 1'b1 1'b0 01111010 */
|
|
|
|
0x001f, /* AICCDETTH[19:16] AICCOFFTH[19:16] 00000000 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0020, /* AICCDETTH[15:8] 01111100 */
|
|
|
|
0x0021, /* AICCDETTH[7:0] 00000000 */
|
|
|
|
0x0022, /* AICCOFFTH[15:8] 00000101 */
|
|
|
|
0x0023, /* AICCOFFTH[7:0] 11100000 */
|
|
|
|
0x0024, /* AICCOPMODE3[1:0] AICCOPMODE2[1:0] AICCOPMODE1[1:0] AICCOPMODE0[1:0] 00000000 */
|
|
|
|
0x0025, /* AICCFIXFREQ3[23:16] 00000000 */
|
|
|
|
0x0026, /* AICCFIXFREQ3[15:8] 00000000 */
|
|
|
|
0x0027, /* AICCFIXFREQ3[7:0] 00000000 */
|
|
|
|
0x0028, /* AICCFIXFREQ2[23:16] 00000000 */
|
|
|
|
0x0029, /* AICCFIXFREQ2[15:8] 00000000 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x002a, /* AICCFIXFREQ2[7:0] 00000000 */
|
|
|
|
0x002b, /* AICCFIXFREQ1[23:16] 00000000 */
|
|
|
|
0x002c, /* AICCFIXFREQ1[15:8] 00000000 */
|
|
|
|
0x002d, /* AICCFIXFREQ1[7:0] 00000000 */
|
|
|
|
0x002e, /* AICCFIXFREQ0[23:16] 00000000 */
|
|
|
|
0x002f, /* AICCFIXFREQ0[15:8] 00000000 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0030, /* AICCFIXFREQ0[7:0] 00000000 */
|
|
|
|
0x0031, /* 1'b0 1'b1 1'b0 1'b0 x DAGC1STER */
|
|
|
|
0x0032, /* DAGC1STEN DAGC1STER */
|
|
|
|
0x0033, /* DAGC1STREF[15:8] 00001010 */
|
|
|
|
0x0034, /* DAGC1STREF[7:0] 11100100 */
|
|
|
|
0x0035, /* DAGC2NDE */
|
|
|
|
0x0036, /* DAGC2NDREF[15:8] 00001010 */
|
|
|
|
0x0037, /* DAGC2NDREF[7:0] 10000000 */
|
|
|
|
0x0038, /* DAGC2NDLOCKDETRNGSEL[1:0] */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x003d, /* 1'b1 SAMGEARS */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0040, /* SAMLFGMA */
|
|
|
|
0x0041, /* SAMLFBWM */
|
|
|
|
0x0044, /* 1'b1 CRGEARSHE */
|
|
|
|
0x0045, /* CRLFGMAN */
|
|
|
|
0x0046, /* CFLFBWMA */
|
|
|
|
0x0047, /* CRLFGMAN */
|
|
|
|
0x0048, /* x x x x CRLFGSTEP_VS[3:0] xxxx1001 */
|
|
|
|
0x0049, /* CRLFBWMA */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x004a, /* CRLFBWMA */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0050, /* 1'b0 1'b1 1'b1 1'b0 MSECALCDA */
|
|
|
|
0x0070, /* TPOUTEN TPIFEN TPCLKOUTE */
|
|
|
|
0x0071, /* TPSENB TPSSOPBITE */
|
|
|
|
0x0073, /* TP47HINS x x CHBERINT PERMODE[1:0] PERINT[1:0] 1xx11100 */
|
|
|
|
0x0075, /* x x x x x IQSWAPCTRL[2:0] xxxxx000 */
|
|
|
|
0x0076, /* NBERCON NBERST NBERPOL NBERWSYN */
|
|
|
|
0x0077, /* x NBERLOSTTH[2:0] NBERACQTH[3:0] x0000000 */
|
|
|
|
0x0078, /* NBERPOLY[31:24] 00000000 */
|
|
|
|
0x0079, /* NBERPOLY[23:16] 00000000 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x007a, /* NBERPOLY[15:8] 00000000 */
|
|
|
|
0x007b, /* NBERPOLY[7:0] 00000000 */
|
|
|
|
0x007c, /* NBERPED[31:24] 00000000 */
|
|
|
|
0x007d, /* NBERPED[23:16] 00000000 */
|
|
|
|
0x007e, /* NBERPED[15:8] 00000000 */
|
|
|
|
0x007f, /* NBERPED[7:0] 00000000 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0080, /* x AGCLOCK DAGCLOCK SYSLOCK x x NEVERLOCK[1:0] */
|
|
|
|
0x0085, /* SPECINVST */
|
|
|
|
0x0088, /* SYSLOCKTIME[15:8] */
|
|
|
|
0x0089, /* SYSLOCKTIME[7:0] */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x008c, /* FECLOCKTIME[15:8] */
|
|
|
|
0x008d, /* FECLOCKTIME[7:0] */
|
|
|
|
0x008e, /* AGCACCOUT[15:8] */
|
|
|
|
0x008f, /* AGCACCOUT[7:0] */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x0090, /* AICCREJSTATUS[3:0] AICCREJBUSY[3:0] */
|
|
|
|
0x0091, /* AICCVSYNC */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x009c, /* CARRFREQOFFSET[15:8] */
|
|
|
|
0x009d, /* CARRFREQOFFSET[7:0] */
|
|
|
|
0x00a1, /* SAMFREQOFFSET[23:16] */
|
|
|
|
0x00a2, /* SAMFREQOFFSET[15:8] */
|
|
|
|
0x00a3, /* SAMFREQOFFSET[7:0] */
|
|
|
|
0x00a6, /* SYNCLOCK SYNCLOCKH */
|
2014-10-25 22:05:05 +08:00
|
|
|
#if 0 /* covered elsewhere */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x00e8, /* CONSTPWR[15:8] */
|
|
|
|
0x00e9, /* CONSTPWR[7:0] */
|
|
|
|
0x00ea, /* BMSE[15:8] */
|
|
|
|
0x00eb, /* BMSE[7:0] */
|
|
|
|
0x00ec, /* MSE[15:8] */
|
|
|
|
0x00ed, /* MSE[7:0] */
|
|
|
|
0x00ee, /* CONSTI[7:0] */
|
|
|
|
0x00ef, /* CONSTQ[7:0] */
|
2014-03-25 06:56:00 +08:00
|
|
|
#endif
|
2014-10-28 20:50:36 +08:00
|
|
|
0x00f4, /* TPIFTPERRCNT[7:0] */
|
|
|
|
0x00f5, /* TPCORREC */
|
|
|
|
0x00f6, /* VBBER[15:8] */
|
|
|
|
0x00f7, /* VBBER[7:0] */
|
|
|
|
0x00f8, /* VABER[15:8] */
|
|
|
|
0x00f9, /* VABER[7:0] */
|
|
|
|
0x00fa, /* TPERRCNT[7:0] */
|
|
|
|
0x00fb, /* NBERLOCK x x x x x x x */
|
|
|
|
0x00fc, /* NBERVALUE[31:24] */
|
|
|
|
0x00fd, /* NBERVALUE[23:16] */
|
|
|
|
0x00fe, /* NBERVALUE[15:8] */
|
|
|
|
0x00ff, /* NBERVALUE[7:0] */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x1000, /* 1'b0 WODAGCOU */
|
|
|
|
0x1005, /* x x 1'b1 1'b1 x SRD_Q_QM */
|
|
|
|
0x1009, /* SRDWAITTIME[7:0] (10msec) 00100011 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x100a, /* SRDWAITTIME_CQS[7:0] (msec) 01100100 */
|
|
|
|
0x101a, /* x 1'b1 1'b0 1'b0 x QMDQAMMODE[2:0] x100x010 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x1036, /* 1'b0 1'b1 1'b0 1'b0 SAMGSEND_CQS[3:0] 01001110 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x103c, /* SAMGSAUTOSTL_V[3:0] SAMGSAUTOEDL_V[3:0] 01000110 */
|
|
|
|
0x103d, /* 1'b1 1'b1 SAMCNORMBP_V[1:0] 1'b0 1'b0 SAMMODESEL_V[1:0] 11100001 */
|
|
|
|
0x103f, /* SAMZTEDSE */
|
|
|
|
0x105d, /* EQSTATUSE */
|
|
|
|
0x105f, /* x PMAPG2_V[2:0] x DMAPG2_V[2:0] x001x011 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x1060, /* 1'b1 EQSTATUSE */
|
|
|
|
0x1061, /* CRMAPBWSTL_V[3:0] CRMAPBWEDL_V[3:0] 00000100 */
|
|
|
|
0x1065, /* 1'b0 x CRMODE_V[1:0] 1'b1 x 1'b1 x 0x111x1x */
|
|
|
|
0x1066, /* 1'b0 1'b0 1'b1 1'b0 1'b1 PNBOOSTSE */
|
|
|
|
0x1068, /* CREPHNGAIN2_V[3:0] CREPHNPBW_V[3:0] 10010001 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x106e, /* x x x x x CREPHNEN_ */
|
|
|
|
0x106f, /* CREPHNTH_V[7:0] 00010101 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x1072, /* CRSWEEPN */
|
|
|
|
0x1073, /* CRPGAIN_V[3:0] x x 1'b1 1'b1 1001xx11 */
|
|
|
|
0x1074, /* CRPBW_V[3:0] x x 1'b1 1'b1 0001xx11 */
|
|
|
|
0x1080, /* DAFTSTATUS[1:0] x x x x x x */
|
|
|
|
0x1081, /* SRDSTATUS[1:0] x x x x x SRDLOCK */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x10a9, /* EQSTATUS_CQS[1:0] x x x x x x */
|
|
|
|
0x10b7, /* EQSTATUS_V[1:0] x x x x x x */
|
2014-10-25 22:05:05 +08:00
|
|
|
#if 0 /* SMART_ANT */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x1f00, /* MODEDETE */
|
|
|
|
0x1f01, /* x x x x x x x SFNRST xxxxxxx0 */
|
|
|
|
0x1f03, /* NUMOFANT[7:0] 10000000 */
|
|
|
|
0x1f04, /* x SELMASK[6:0] x0000000 */
|
|
|
|
0x1f05, /* x SETMASK[6:0] x0000000 */
|
|
|
|
0x1f06, /* x TXDATA[6:0] x0000000 */
|
|
|
|
0x1f07, /* x CHNUMBER[6:0] x0000000 */
|
|
|
|
0x1f09, /* AGCTIME[23:16] 10011000 */
|
|
|
|
0x1f0a, /* AGCTIME[15:8] 10010110 */
|
|
|
|
0x1f0b, /* AGCTIME[7:0] 10000000 */
|
|
|
|
0x1f0c, /* ANTTIME[31:24] 00000000 */
|
|
|
|
0x1f0d, /* ANTTIME[23:16] 00000011 */
|
|
|
|
0x1f0e, /* ANTTIME[15:8] 10010000 */
|
|
|
|
0x1f0f, /* ANTTIME[7:0] 10010000 */
|
|
|
|
0x1f11, /* SYNCTIME[23:16] 10011000 */
|
|
|
|
0x1f12, /* SYNCTIME[15:8] 10010110 */
|
|
|
|
0x1f13, /* SYNCTIME[7:0] 10000000 */
|
|
|
|
0x1f14, /* SNRTIME[31:24] 00000001 */
|
|
|
|
0x1f15, /* SNRTIME[23:16] 01111101 */
|
|
|
|
0x1f16, /* SNRTIME[15:8] 01111000 */
|
|
|
|
0x1f17, /* SNRTIME[7:0] 01000000 */
|
|
|
|
0x1f19, /* FECTIME[23:16] 00000000 */
|
|
|
|
0x1f1a, /* FECTIME[15:8] 01110010 */
|
|
|
|
0x1f1b, /* FECTIME[7:0] 01110000 */
|
|
|
|
0x1f1d, /* FECTHD[7:0] 00000011 */
|
|
|
|
0x1f1f, /* SNRTHD[23:16] 00001000 */
|
|
|
|
0x1f20, /* SNRTHD[15:8] 01111111 */
|
|
|
|
0x1f21, /* SNRTHD[7:0] 10000101 */
|
|
|
|
0x1f80, /* IRQFLG x x SFSDRFLG MODEBFLG SAVEFLG SCANFLG TRACKFLG */
|
|
|
|
0x1f81, /* x SYNCCON SNRCON FECCON x STDBUSY SYNCRST AGCFZCO */
|
|
|
|
0x1f82, /* x x x SCANOPCD[4:0] */
|
|
|
|
0x1f83, /* x x x x MAINOPCD[3:0] */
|
|
|
|
0x1f84, /* x x RXDATA[13:8] */
|
|
|
|
0x1f85, /* RXDATA[7:0] */
|
|
|
|
0x1f86, /* x x SDTDATA[13:8] */
|
|
|
|
0x1f87, /* SDTDATA[7:0] */
|
|
|
|
0x1f89, /* ANTSNR[23:16] */
|
|
|
|
0x1f8a, /* ANTSNR[15:8] */
|
|
|
|
0x1f8b, /* ANTSNR[7:0] */
|
|
|
|
0x1f8c, /* x x x x ANTFEC[13:8] */
|
|
|
|
0x1f8d, /* ANTFEC[7:0] */
|
|
|
|
0x1f8e, /* MAXCNT[7:0] */
|
|
|
|
0x1f8f, /* SCANCNT[7:0] */
|
|
|
|
0x1f91, /* MAXPW[23:16] */
|
|
|
|
0x1f92, /* MAXPW[15:8] */
|
|
|
|
0x1f93, /* MAXPW[7:0] */
|
|
|
|
0x1f95, /* CURPWMSE[23:16] */
|
|
|
|
0x1f96, /* CURPWMSE[15:8] */
|
|
|
|
0x1f97, /* CURPWMSE[7:0] */
|
2014-10-25 22:05:05 +08:00
|
|
|
#endif /* SMART_ANT */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x211f, /* 1'b1 1'b1 1'b1 CIRQEN x x 1'b0 1'b0 1111xx00 */
|
|
|
|
0x212a, /* EQAUTOST */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x2122, /* CHFAST[7:0] 01100000 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x212b, /* FFFSTEP_V[3:0] x FBFSTEP_V[2:0] 0001x001 */
|
|
|
|
0x212c, /* PHDEROTBWSEL[3:0] 1'b1 1'b1 1'b1 1'b0 10001110 */
|
|
|
|
0x212d, /* 1'b1 1'b1 1'b1 1'b1 x x TPIFLOCKS */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x2135, /* DYNTRACKFDEQ[3:0] x 1'b0 1'b0 1'b0 1010x000 */
|
|
|
|
0x2141, /* TRMODE[1:0] 1'b1 1'b1 1'b0 1'b1 1'b1 1'b1 01110111 */
|
|
|
|
0x2162, /* AICCCTRLE */
|
|
|
|
0x2173, /* PHNCNFCNT[7:0] 00000100 */
|
|
|
|
0x2179, /* 1'b0 1'b0 1'b0 1'b1 x BADSINGLEDYNTRACKFBF[2:0] 0001x001 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x217a, /* 1'b0 1'b0 1'b0 1'b1 x BADSLOWSINGLEDYNTRACKFBF[2:0] 0001x001 */
|
|
|
|
0x217e, /* CNFCNTTPIF[7:0] 00001000 */
|
|
|
|
0x217f, /* TPERRCNTTPIF[7:0] 00000001 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x2180, /* x x x x x x FBDLYCIR[9:8] */
|
|
|
|
0x2181, /* FBDLYCIR[7:0] */
|
|
|
|
0x2185, /* MAXPWRMAIN[7:0] */
|
|
|
|
0x2191, /* NCOMBDET x x x x x x x */
|
|
|
|
0x2199, /* x MAINSTRON */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x219a, /* FFFEQSTEPOUT_V[3:0] FBFSTEPOUT_V[2:0] */
|
|
|
|
0x21a1, /* x x SNRREF[5:0] */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x2845, /* 1'b0 1'b1 x x FFFSTEP_CQS[1:0] FFFCENTERTAP[1:0] 01xx1110 */
|
|
|
|
0x2846, /* 1'b0 x 1'b0 1'b1 FBFSTEP_CQS[1:0] 1'b1 1'b0 0x011110 */
|
|
|
|
0x2847, /* ENNOSIGDE */
|
|
|
|
0x2849, /* 1'b1 1'b1 NOUSENOSI */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x284a, /* EQINITWAITTIME[7:0] 01100100 */
|
2014-10-25 22:12:25 +08:00
|
|
|
0x3000, /* 1'b1 1'b1 1'b1 x x x 1'b0 RPTRSTM */
|
|
|
|
0x3001, /* RPTRSTWAITTIME[7:0] (100msec) 00110010 */
|
|
|
|
0x3031, /* FRAMELOC */
|
|
|
|
0x3032, /* 1'b1 1'b0 1'b0 1'b0 x x FRAMELOCKMODE_CQS[1:0] 1000xx11 */
|
2014-10-28 20:50:36 +08:00
|
|
|
0x30a9, /* VDLOCK_Q FRAMELOCK */
|
|
|
|
0x30aa, /* MPEGLOCK */
|
2014-03-25 06:56:00 +08:00
|
|
|
};
|
|
|
|
|
2017-09-03 20:19:31 +08:00
|
|
|
#define numDumpRegs (ARRAY_SIZE(regtab))
|
2014-03-25 06:56:00 +08:00
|
|
|
static u8 regval1[numDumpRegs] = {0, };
|
|
|
|
static u8 regval2[numDumpRegs] = {0, };
|
|
|
|
|
|
|
|
static void lgdt3306a_DumpAllRegs(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
memset(regval2, 0xff, sizeof(regval2));
|
|
|
|
lgdt3306a_DumpRegs(state);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lgdt3306a_DumpRegs(struct lgdt3306a_state *state)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int sav_debug = debug;
|
2014-07-28 06:24:24 +08:00
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
if ((debug & DBG_DUMP) == 0)
|
|
|
|
return;
|
2014-10-25 22:20:57 +08:00
|
|
|
debug &= ~DBG_REG; /* suppress DBG_REG during reg dump */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
lg_debug("\n");
|
2014-03-25 06:56:00 +08:00
|
|
|
|
2014-07-28 06:24:24 +08:00
|
|
|
for (i = 0; i < numDumpRegs; i++) {
|
2014-03-25 06:56:00 +08:00
|
|
|
lgdt3306a_read_reg(state, regtab[i], ®val1[i]);
|
2014-07-28 06:24:24 +08:00
|
|
|
if (regval1[i] != regval2[i]) {
|
[media] lbdt3306a: rework at printk macros
Use pr_foo() where there's a direct replacement. For debug, use
custom-made macros, for now, as there are 3 different debug levels.
We should get rid of those some day, specially since several such
macros can be just removed, as Kernel trace would provide about
the same output.
This gets rid of some checkpatch errors:
WARNING: Prefer [subsystem eg: netdev]_info([subsystem]dev, ... then dev_info(dev, ... then pr_info(... to printk(KERN_INFO ...
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3306a: " fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
ERROR: Macros with complex values should be enclosed in parentheses
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2014-10-28 21:35:16 +08:00
|
|
|
lg_debug(" %04X = %02X\n", regtab[i], regval1[i]);
|
2015-04-29 05:31:21 +08:00
|
|
|
regval2[i] = regval1[i];
|
2014-03-25 06:56:00 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
debug = sav_debug;
|
|
|
|
}
|
2014-07-28 06:24:24 +08:00
|
|
|
#endif /* DBG_DUMP */
|
2014-03-25 06:56:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-10 05:32:21 +08:00
|
|
|
static const struct dvb_frontend_ops lgdt3306a_ops = {
|
2014-03-25 06:56:00 +08:00
|
|
|
.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
|
|
|
|
.info = {
|
|
|
|
.name = "LG Electronics LGDT3306A VSB/QAM Frontend",
|
|
|
|
.frequency_min = 54000000,
|
2014-07-28 06:24:24 +08:00
|
|
|
.frequency_max = 858000000,
|
2014-03-25 06:56:00 +08:00
|
|
|
.frequency_stepsize = 62500,
|
|
|
|
.caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
|
|
|
|
},
|
|
|
|
.i2c_gate_ctrl = lgdt3306a_i2c_gate_ctrl,
|
|
|
|
.init = lgdt3306a_init,
|
|
|
|
.sleep = lgdt3306a_fe_sleep,
|
|
|
|
/* if this is set, it overrides the default swzigzag */
|
|
|
|
.tune = lgdt3306a_tune,
|
|
|
|
.set_frontend = lgdt3306a_set_parameters,
|
|
|
|
.get_frontend = lgdt3306a_get_frontend,
|
|
|
|
.get_frontend_algo = lgdt3306a_get_frontend_algo,
|
|
|
|
.get_tune_settings = lgdt3306a_get_tune_settings,
|
|
|
|
.read_status = lgdt3306a_read_status,
|
|
|
|
.read_ber = lgdt3306a_read_ber,
|
|
|
|
.read_signal_strength = lgdt3306a_read_signal_strength,
|
|
|
|
.read_snr = lgdt3306a_read_snr,
|
|
|
|
.read_ucblocks = lgdt3306a_read_ucblocks,
|
|
|
|
.release = lgdt3306a_release,
|
|
|
|
.ts_bus_ctrl = lgdt3306a_ts_bus_ctrl,
|
|
|
|
.search = lgdt3306a_search,
|
|
|
|
};
|
|
|
|
|
2017-01-10 11:14:18 +08:00
|
|
|
static int lgdt3306a_select(struct i2c_mux_core *muxc, u32 chan)
|
|
|
|
{
|
|
|
|
struct i2c_client *client = i2c_mux_priv(muxc);
|
|
|
|
struct lgdt3306a_state *state = i2c_get_clientdata(client);
|
|
|
|
|
|
|
|
return lgdt3306a_i2c_gate_ctrl(&state->frontend, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_deselect(struct i2c_mux_core *muxc, u32 chan)
|
|
|
|
{
|
|
|
|
struct i2c_client *client = i2c_mux_priv(muxc);
|
|
|
|
struct lgdt3306a_state *state = i2c_get_clientdata(client);
|
|
|
|
|
|
|
|
return lgdt3306a_i2c_gate_ctrl(&state->frontend, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_probe(struct i2c_client *client,
|
|
|
|
const struct i2c_device_id *id)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_config *config;
|
|
|
|
struct lgdt3306a_state *state;
|
|
|
|
struct dvb_frontend *fe;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
config = kzalloc(sizeof(struct lgdt3306a_config), GFP_KERNEL);
|
|
|
|
if (config == NULL) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(config, client->dev.platform_data,
|
|
|
|
sizeof(struct lgdt3306a_config));
|
|
|
|
|
|
|
|
config->i2c_addr = client->addr;
|
|
|
|
fe = lgdt3306a_attach(config, client->adapter);
|
|
|
|
if (fe == NULL) {
|
|
|
|
ret = -ENODEV;
|
|
|
|
goto err_fe;
|
|
|
|
}
|
|
|
|
|
|
|
|
i2c_set_clientdata(client, fe->demodulator_priv);
|
|
|
|
state = fe->demodulator_priv;
|
2018-01-05 08:04:17 +08:00
|
|
|
state->frontend.ops.release = NULL;
|
2017-01-10 11:14:18 +08:00
|
|
|
|
|
|
|
/* create mux i2c adapter for tuner */
|
|
|
|
state->muxc = i2c_mux_alloc(client->adapter, &client->dev,
|
|
|
|
1, 0, I2C_MUX_LOCKED,
|
|
|
|
lgdt3306a_select, lgdt3306a_deselect);
|
|
|
|
if (!state->muxc) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
goto err_kfree;
|
|
|
|
}
|
|
|
|
state->muxc->priv = client;
|
|
|
|
ret = i2c_mux_add_adapter(state->muxc, 0, 0, 0);
|
|
|
|
if (ret)
|
|
|
|
goto err_kfree;
|
|
|
|
|
|
|
|
/* create dvb_frontend */
|
|
|
|
fe->ops.i2c_gate_ctrl = NULL;
|
|
|
|
*config->i2c_adapter = state->muxc->adapter[0];
|
|
|
|
*config->fe = fe;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_kfree:
|
|
|
|
kfree(state);
|
|
|
|
err_fe:
|
|
|
|
kfree(config);
|
|
|
|
fail:
|
|
|
|
dev_dbg(&client->dev, "failed=%d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lgdt3306a_remove(struct i2c_client *client)
|
|
|
|
{
|
|
|
|
struct lgdt3306a_state *state = i2c_get_clientdata(client);
|
|
|
|
|
|
|
|
i2c_mux_del_adapters(state->muxc);
|
|
|
|
|
|
|
|
state->frontend.ops.release = NULL;
|
|
|
|
state->frontend.demodulator_priv = NULL;
|
|
|
|
|
|
|
|
kfree(state->cfg);
|
|
|
|
kfree(state);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct i2c_device_id lgdt3306a_id_table[] = {
|
|
|
|
{"lgdt3306a", 0},
|
|
|
|
{}
|
|
|
|
};
|
|
|
|
MODULE_DEVICE_TABLE(i2c, lgdt3306a_id_table);
|
|
|
|
|
|
|
|
static struct i2c_driver lgdt3306a_driver = {
|
|
|
|
.driver = {
|
|
|
|
.name = "lgdt3306a",
|
|
|
|
.suppress_bind_attrs = true,
|
|
|
|
},
|
|
|
|
.probe = lgdt3306a_probe,
|
|
|
|
.remove = lgdt3306a_remove,
|
|
|
|
.id_table = lgdt3306a_id_table,
|
|
|
|
};
|
|
|
|
|
|
|
|
module_i2c_driver(lgdt3306a_driver);
|
|
|
|
|
2014-03-25 06:56:00 +08:00
|
|
|
MODULE_DESCRIPTION("LG Electronics LGDT3306A ATSC/QAM-B Demodulator Driver");
|
|
|
|
MODULE_AUTHOR("Fred Richter <frichter@hauppauge.com>");
|
|
|
|
MODULE_LICENSE("GPL");
|
|
|
|
MODULE_VERSION("0.2");
|