// SPDX-License-Identifier: GPL-2.0-or-later
/*
* descriptions + helper functions for simple dvb plls.
*
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/idr.h>
#include <linux/dvb/frontend.h>
#include <asm/types.h>
#include "dvb-pll.h"
#define dprintk(fmt, arg...) \
printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg)
struct dvb_pll_priv {
/* pll number */
int nr;
/* i2c details */
int pll_i2c_address;
struct i2c_adapter *i2c;
/* the PLL descriptor */
const struct dvb_pll_desc *pll_desc;
/* cached frequency/bandwidth */
u32 frequency;
u32 bandwidth;
};
#define DVB_PLL_MAX 64
static DEFINE_IDA(pll_ida);
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable verbose debug messages");
static unsigned int id[DVB_PLL_MAX] =
{ [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
module_param_array(id, int, NULL, 0644);
MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
/* ----------------------------------------------------------- */
struct dvb_pll_desc {
const char *name;
u32 min;
u32 max;
u32 iffreq;
void (*set)(struct dvb_frontend *fe, u8 *buf);
u8 *initdata;
u8 *initdata2;
u8 *sleepdata;
int count;
struct {
u32 limit;
u32 stepsize;
u8 config;
u8 cb;
} entries[];
};
/* ----------------------------------------------------------- */
/* descriptions */
static const struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
.name = "Thomson dtt7579",
.min = 177 * MHz,
.max = 858 * MHz,
.iffreq= 36166667,
.sleepdata = (u8[]){ 2, 0xb4, 0x03 },
.count = 4,
.entries = {
{ 443250000, 166667, 0xb4, 0x02 },
{ 542000000, 166667, 0xb4, 0x08 },
{ 771000000, 166667, 0xbc, 0x08 },
{ 999999999, 166667, 0xf4, 0x08 },
},
};
static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
{
u32 bw = fe->dtv_property_cache.bandwidth_hz;
if (bw == 7000000)
buf[3] |= 0x10;
}
static const struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
.name = "Thomson dtt759x",
.min = 177 * MHz,
.max = 896 * MHz,
.set = thomson_dtt759x_bw,
.iffreq= 36166667,
.sleepdata = (u8[]){ 2, 0x84, 0x03 },
.count = 5,
.entries = {
{ 264000000, 166667, 0xb4, 0x02 },
{ 470000000, 166667, 0xbc, 0x02 },
{ 735000000, 166667, 0xbc, 0x08 },
{ 835000000, 166667, 0xf4, 0x08 },
{ 999999999, 166667, 0xfc, 0x08 },
},
};
static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
{
u32 bw = fe->dtv_property_cache.bandwidth_hz;
if (bw == 8000000)
buf[3] ^= 0x10;
}
static const struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
.name = "Thomson dtt7520x",
.min = 185 * MHz,
.max = 900 * MHz,
.set = thomson_dtt7520x_bw,
.iffreq = 36166667,
.count = 7,
.entries = {
{ 305000000, 166667, 0xb4, 0x12 },
{ 405000000, 166667, 0xbc, 0x12 },
{ 445000000, 166667, 0xbc, 0x12 },
{ 465000000, 166667, 0xf4, 0x18 },
{ 735000000, 166667, 0xfc, 0x18 },
{ 835000000, 166667, 0xbc, 0x18 },
{ 999999999, 166667, 0xfc, 0x18 },
},
};
static const struct dvb_pll_desc dvb_pll_lg_z201 = {
.name = "LG z201",
.min = 174 * MHz,
.max = 862 * MHz,
.iffreq= 36166667,
.sleepdata = (u8[]){ 2, 0xbc, 0x03 },
.count = 5,
.entries = {
{ 157500000, 166667, 0xbc, 0x01 },
{ 443250000, 166667, 0xbc, 0x02 },
{ 542000000, 166667, 0xbc, 0x04 },
{ 830000000, 166667, 0xf4, 0x04 },
{ 999999999, 166667, 0xfc, 0x04 },
},
};
static const struct dvb_pll_desc dvb_pll_unknown_1 = {
.name = "unknown 1", /* used by dntv live dvb-t */
.min = 174 * MHz,
.max = 862 * MHz,
.iffreq= 36166667,
.count = 9,
.entries = {
{ 150000000, 166667, 0xb4, 0x01 },
{ 173000000, 166667, 0xbc, 0x01 },
{ 250000000, 166667, 0xb4, 0x02 },
{ 400000000, 166667, 0xbc, 0x02 },
{ 420000000, 166667, 0xf4, 0x02 },
{ 470000000, 166667, 0xfc, 0x02 },
{ 600000000, 166667, 0xbc, 0x08 },
{ 730000000, 166667, 0xf4, 0x08 },
{ 999999999, 166667, 0xfc, 0x08 },
},
};
/* Infineon TUA6010XS
* used in Thomson Cable Tuner
*/
static const struct dvb_pll_desc dvb_pll_tua6010xs = {
.name = "Infineon TUA6010XS",
.min = 44250 * kHz,
.max = 858 * MHz,
.iffreq= 36125000,
.count = 3,
.entries = {
{ 115750000, 62500, 0x8e, 0x03 },
{ 403250000,