^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * descriptions + helper functions for simple dvb plls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/dvb/frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "dvb-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define dprintk(fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) printk(KERN_DEBUG pr_fmt("%s: " fmt), __func__, ##arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct dvb_pll_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* pll number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* i2c details */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int pll_i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* the PLL descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) const struct dvb_pll_desc *pll_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* cached frequency/bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u32 frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u32 bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define DVB_PLL_MAX 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static DEFINE_IDA(pll_ida);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) MODULE_PARM_DESC(debug, "enable verbose debug messages");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static unsigned int id[DVB_PLL_MAX] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) module_param_array(id, int, NULL, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* ----------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct dvb_pll_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u32 min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u32 max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u32 iffreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) void (*set)(struct dvb_frontend *fe, u8 *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 *initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 *initdata2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u8 *sleepdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u32 stepsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u8 config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u8 cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) } entries[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /* ----------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* descriptions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static const struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .name = "Thomson dtt7579",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .min = 177 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) { 443250000, 166667, 0xb4, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { 542000000, 166667, 0xb4, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) { 771000000, 166667, 0xbc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) { 999999999, 166667, 0xf4, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u32 bw = fe->dtv_property_cache.bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (bw == 7000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) buf[3] |= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static const struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) .name = "Thomson dtt759x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .min = 177 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .max = 896 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .set = thomson_dtt759x_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .sleepdata = (u8[]){ 2, 0x84, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .count = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) { 264000000, 166667, 0xb4, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) { 470000000, 166667, 0xbc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) { 735000000, 166667, 0xbc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) { 835000000, 166667, 0xf4, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) { 999999999, 166667, 0xfc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static void thomson_dtt7520x_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u32 bw = fe->dtv_property_cache.bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (bw == 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) buf[3] ^= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) static const struct dvb_pll_desc dvb_pll_thomson_dtt7520x = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .name = "Thomson dtt7520x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .min = 185 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .max = 900 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .set = thomson_dtt7520x_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .iffreq = 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .count = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) { 305000000, 166667, 0xb4, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) { 405000000, 166667, 0xbc, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) { 445000000, 166667, 0xbc, 0x12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { 465000000, 166667, 0xf4, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) { 735000000, 166667, 0xfc, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) { 835000000, 166667, 0xbc, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) { 999999999, 166667, 0xfc, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static const struct dvb_pll_desc dvb_pll_lg_z201 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .name = "LG z201",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .min = 174 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .max = 862 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .count = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { 157500000, 166667, 0xbc, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) { 443250000, 166667, 0xbc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) { 542000000, 166667, 0xbc, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) { 830000000, 166667, 0xf4, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { 999999999, 166667, 0xfc, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static const struct dvb_pll_desc dvb_pll_unknown_1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .name = "unknown 1", /* used by dntv live dvb-t */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .min = 174 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .max = 862 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) .count = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) { 150000000, 166667, 0xb4, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { 173000000, 166667, 0xbc, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { 250000000, 166667, 0xb4, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { 400000000, 166667, 0xbc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { 420000000, 166667, 0xf4, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) { 470000000, 166667, 0xfc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) { 600000000, 166667, 0xbc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { 730000000, 166667, 0xf4, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { 999999999, 166667, 0xfc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* Infineon TUA6010XS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * used in Thomson Cable Tuner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static const struct dvb_pll_desc dvb_pll_tua6010xs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .name = "Infineon TUA6010XS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .min = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .iffreq= 36125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) { 115750000, 62500, 0x8e, 0x03 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) { 403250000, 62500, 0x8e, 0x06 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) { 999999999, 62500, 0x8e, 0x85 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /* Panasonic env57h1xd5 (some Philips PLL ?) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static const struct dvb_pll_desc dvb_pll_env57h1xd5 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .name = "Panasonic ENV57H1XD5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .min = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .iffreq= 36125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) { 153000000, 166667, 0xc2, 0x41 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) { 470000000, 166667, 0xc2, 0x42 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) { 526000000, 166667, 0xc2, 0x84 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { 999999999, 166667, 0xc2, 0xa4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Philips TDA6650/TDA6651
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * used in Panasonic ENV77H11D5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static void tda665x_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 bw = fe->dtv_property_cache.bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (bw == 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) buf[3] |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static const struct dvb_pll_desc dvb_pll_tda665x = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) .name = "Philips TDA6650/TDA6651",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) .min = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .set = tda665x_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .count = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) /* Infineon TUA6034
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * used in LG TDTP E102P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static void tua6034_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) u32 bw = fe->dtv_property_cache.bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (bw == 7000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) buf[3] |= 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static const struct dvb_pll_desc dvb_pll_tua6034 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .name = "Infineon TUA6034",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .min = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .set = tua6034_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) { 174500000, 62500, 0xce, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { 230000000, 62500, 0xce, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) { 999999999, 62500, 0xce, 0x04 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* ALPS TDED4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * used in Nebula-Cards and USB boxes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void tded4_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) u32 bw = fe->dtv_property_cache.bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (bw == 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) buf[3] |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static const struct dvb_pll_desc dvb_pll_tded4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .name = "ALPS TDED4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .min = 47 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .max = 863 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) .iffreq= 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) .set = tded4_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) { 153000000, 166667, 0x85, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) { 470000000, 166667, 0x85, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { 823000000, 166667, 0x85, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) { 999999999, 166667, 0x85, 0x88 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* ALPS TDHU2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * used in AverTVHD MCE A180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static const struct dvb_pll_desc dvb_pll_tdhu2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .name = "ALPS TDHU2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .min = 54 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .max = 864 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .iffreq= 44000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) { 162000000, 62500, 0x85, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { 426000000, 62500, 0x85, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) { 782000000, 62500, 0x85, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) { 999999999, 62500, 0x85, 0x88 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* Samsung TBMV30111IN / TBMV30712IN1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * used in Air2PC ATSC - 2nd generation (nxt2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static const struct dvb_pll_desc dvb_pll_samsung_tbmv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .name = "Samsung TBMV30111IN / TBMV30712IN1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .min = 54 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .max = 860 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .iffreq= 44000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .count = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { 172000000, 166667, 0xb4, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) { 214000000, 166667, 0xb4, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) { 467000000, 166667, 0xbc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) { 721000000, 166667, 0xbc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) { 841000000, 166667, 0xf4, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) { 999999999, 166667, 0xfc, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Philips SD1878 Tuner.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static const struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .name = "Philips SD1878",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .min = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .max = 2150 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .iffreq= 249, /* zero-IF, offset 249 is to round up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) { 1250000, 500, 0xc4, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) { 1450000, 500, 0xc4, 0x40},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { 2050000, 500, 0xc4, 0x80},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) { 2150000, 500, 0xc4, 0xc0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static void opera1_bw(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u32 b_w = (c->symbol_rate * 27) / 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) .addr = priv->pll_i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .len = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) u8 lpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) result = i2c_transfer(priv->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (result != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pr_err("%s: i2c_transfer failed:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (b_w <= 10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) lpf = 0xc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) else if (b_w <= 12000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) lpf = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) else if (b_w <= 14000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) lpf = 0xa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) else if (b_w <= 16000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) lpf = 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) else if (b_w <= 18000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) lpf = 0xe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) else if (b_w <= 20000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) lpf = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) else if (b_w <= 22000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) lpf = 0x9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) else if (b_w <= 24000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) lpf = 0x5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) else if (b_w <= 26000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) lpf = 0xd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) else if (b_w <= 28000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) lpf = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) lpf = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) buf[2] ^= 0x1c; /* Flip bits 3-5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* Set lpf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) buf[2] |= ((lpf >> 2) & 0x3) << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) buf[3] |= (lpf & 0x3) << 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static const struct dvb_pll_desc dvb_pll_opera1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .name = "Opera Tuner",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .min = 900 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .max = 2250 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) .iffreq= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) .set = opera1_bw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) .count = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) { 1064000, 500, 0xf9, 0xc2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { 1169000, 500, 0xf9, 0xe2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { 1299000, 500, 0xf9, 0x20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { 1444000, 500, 0xf9, 0x40 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { 1606000, 500, 0xf9, 0x60 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) { 1777000, 500, 0xf9, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { 1941000, 500, 0xf9, 0xa0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) { 2250000, 500, 0xf9, 0xc0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .addr = priv->pll_i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) .len = 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) result = i2c_transfer(priv->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (result != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) pr_err("%s: i2c_transfer failed:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) buf[2] = 0x9e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) buf[3] = 0x90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static const struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .name = "Samsung DTOS403IH102A",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .min = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .max = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .iffreq = 36125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .count = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) .set = samsung_dtos403ih102a_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) { 135000000, 62500, 0xbe, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { 177000000, 62500, 0xf6, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) { 370000000, 62500, 0xbe, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) { 450000000, 62500, 0xf6, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) { 466000000, 62500, 0xfe, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) { 538000000, 62500, 0xbe, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) { 826000000, 62500, 0xf6, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) { 999999999, 62500, 0xfe, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) static const struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .name = "Samsung TDTC9251DH0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .min = 48 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .max = 863 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .iffreq = 36166667,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) { 157500000, 166667, 0xcc, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) { 443000000, 166667, 0xcc, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) { 863000000, 166667, 0xcc, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static const struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) .name = "Samsung TBDU18132",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .min = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .max = 2150 * MHz, /* guesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .iffreq = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) { 1550000, 125, 0x84, 0x82 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) { 4095937, 125, 0x84, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * by this driver. The two extra bits are 0x60 in the third byte. 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * bits is enough for over 4 GHz, which is enough to cover the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * of this tuner. We could use the additional divisor bits by adding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * more entries, e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static const struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .name = "Samsung TBMU24112",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .min = 950 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .max = 2150 * MHz, /* guesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .iffreq = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) { 1500000, 125, 0x84, 0x18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { 9999999, 125, 0x84, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* byte 4 : 1 * * AGD R3 R2 R1 R0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * 47 - 153 0 * 0 0 0 0 0 1 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * 153 - 430 0 * 0 0 0 0 1 0 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * 430 - 822 0 * 0 0 1 0 0 0 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * 822 - 862 1 * 0 0 1 0 0 0 0x88 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static const struct dvb_pll_desc dvb_pll_alps_tdee4 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) .name = "ALPS TDEE4",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) .min = 47 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) .max = 862 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .iffreq = 36125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) .count = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) { 153000000, 62500, 0x95, 0x01 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) { 430000000, 62500, 0x95, 0x02 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) { 822000000, 62500, 0x95, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) { 999999999, 62500, 0x95, 0x88 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Infineon TUA6034 ISDB-T, used in Friio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* CP cur. 50uA, AGC takeover: 103dBuV, PORT3 on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static const struct dvb_pll_desc dvb_pll_tua6034_friio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) .name = "Infineon TUA6034 ISDB-T (Friio)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) .min = 90 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) .max = 770 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) .iffreq = 57000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) .initdata = (u8[]){ 4, 0x9a, 0x50, 0xb2, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) .sleepdata = (u8[]){ 4, 0x9a, 0x70, 0xb3, 0x0b },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) .count = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) { 170000000, 142857, 0xba, 0x09 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) { 470000000, 142857, 0xba, 0x0a },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) { 770000000, 142857, 0xb2, 0x08 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Philips TDA6651 ISDB-T, used in Earthsoft PT1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static const struct dvb_pll_desc dvb_pll_tda665x_earth_pt1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .name = "Philips TDA6651 ISDB-T (EarthSoft PT1)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .min = 90 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) .max = 770 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) .iffreq = 57000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) .initdata = (u8[]){ 5, 0x0e, 0x7f, 0xc1, 0x80, 0x80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) .count = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) .entries = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) { 140000000, 142857, 0xc1, 0x81 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) { 170000000, 142857, 0xc1, 0xa1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) { 220000000, 142857, 0xc1, 0x62 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) { 330000000, 142857, 0xc1, 0xa2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) { 402000000, 142857, 0xc1, 0xe2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) { 450000000, 142857, 0xc1, 0x64 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) { 550000000, 142857, 0xc1, 0x84 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) { 600000000, 142857, 0xc1, 0xa4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) { 700000000, 142857, 0xc1, 0xc4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) { 770000000, 142857, 0xc1, 0xe4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* ----------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static const struct dvb_pll_desc *pll_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) [DVB_PLL_UNDEFINED] = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) [DVB_PLL_THOMSON_DTT7520X] = &dvb_pll_thomson_dtt7520x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) [DVB_PLL_TUA6034] = &dvb_pll_tua6034,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) [DVB_PLL_TDA665X] = &dvb_pll_tda665x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) [DVB_PLL_TDED4] = &dvb_pll_tded4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) [DVB_PLL_TDEE4] = &dvb_pll_alps_tdee4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) [DVB_PLL_TDHU2] = &dvb_pll_tdhu2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) [DVB_PLL_OPERA1] = &dvb_pll_opera1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) [DVB_PLL_SAMSUNG_TDTC9251DH0] = &dvb_pll_samsung_tdtc9251dh0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) [DVB_PLL_SAMSUNG_TBDU18132] = &dvb_pll_samsung_tbdu18132,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) [DVB_PLL_SAMSUNG_TBMU24112] = &dvb_pll_samsung_tbmu24112,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) [DVB_PLL_TUA6034_FRIIO] = &dvb_pll_tua6034_friio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) [DVB_PLL_TDA665X_EARTH_PT1] = &dvb_pll_tda665x_earth_pt1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* ----------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) const u32 frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) const struct dvb_pll_desc *desc = priv->pll_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) for (i = 0; i < desc->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (frequency > desc->entries[i].limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dprintk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) frequency, i, desc->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (i == desc->count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) div = (frequency + desc->iffreq +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) buf[0] = div >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) buf[1] = div & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) buf[2] = desc->entries[i].config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) buf[3] = desc->entries[i].cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (desc->set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) desc->set(fe, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) dprintk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) desc->name, div, buf[0], buf[1], buf[2], buf[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) // calculate the frequency we set it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return (div * desc->entries[i].stepsize) - desc->iffreq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static void dvb_pll_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) kfree(fe->tuner_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int dvb_pll_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (priv->i2c == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (priv->pll_desc->sleepdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct i2c_msg msg = { .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) .addr = priv->pll_i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) .buf = priv->pll_desc->sleepdata + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .len = priv->pll_desc->sleepdata[0] };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* Shouldn't be called when initdata is NULL, maybe BUG()? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static int dvb_pll_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct i2c_msg msg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) { .addr = priv->pll_i2c_address, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .buf = buf, .len = sizeof(buf) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) u32 frequency = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (priv->i2c == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) result = dvb_pll_configure(fe, buf, c->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) frequency = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) priv->frequency = frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) priv->bandwidth = c->bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static int dvb_pll_calc_regs(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) u8 *buf, int buf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) u32 frequency = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (buf_len < 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) result = dvb_pll_configure(fe, buf + 1, c->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) frequency = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) buf[0] = priv->pll_i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) priv->frequency = frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) priv->bandwidth = c->bandwidth_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) *frequency = priv->frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) *bandwidth = priv->bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static int dvb_pll_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (priv->i2c == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (priv->pll_desc->initdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct i2c_msg msg = { .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .addr = priv->pll_i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .buf = priv->pll_desc->initdata + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .len = priv->pll_desc->initdata[0] };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) result = i2c_transfer(priv->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (result != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (priv->pll_desc->initdata2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) msg.buf = priv->pll_desc->initdata2 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) msg.len = priv->pll_desc->initdata2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) result = i2c_transfer(priv->i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (result != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /* Shouldn't be called when initdata is NULL, maybe BUG()? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static const struct dvb_tuner_ops dvb_pll_tuner_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) .release = dvb_pll_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) .sleep = dvb_pll_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .init = dvb_pll_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) .set_params = dvb_pll_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) .calc_regs = dvb_pll_calc_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .get_frequency = dvb_pll_get_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) .get_bandwidth = dvb_pll_get_bandwidth,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct i2c_adapter *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) unsigned int pll_desc_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) u8 *b1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .len = 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct dvb_pll_priv *priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) const struct dvb_pll_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) int nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) b1 = kmalloc(1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (!b1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) b1[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) msg.buf = b1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) nr = ida_simple_get(&pll_ida, 0, DVB_PLL_MAX, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (nr < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) kfree(b1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (id[nr] > DVB_PLL_UNDEFINED && id[nr] < ARRAY_SIZE(pll_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) pll_desc_id = id[nr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) desc = pll_list[pll_desc_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (i2c != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) ret = i2c_transfer (i2c, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) priv->pll_i2c_address = pll_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) priv->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) priv->pll_desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) priv->nr = nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) strscpy(fe->ops.tuner_ops.info.name, desc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) sizeof(fe->ops.tuner_ops.info.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) fe->ops.tuner_ops.info.frequency_min_hz = desc->min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) fe->ops.tuner_ops.info.frequency_max_hz = desc->max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) dprintk("%s tuner, frequency range: %u...%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) desc->name, desc->min, desc->max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!desc->initdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) fe->ops.tuner_ops.init = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) if (!desc->sleepdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) fe->ops.tuner_ops.sleep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) fe->tuner_priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if ((debug) || (id[priv->nr] == pll_desc_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dprintk("dvb-pll[%d]", priv->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (i2c != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) pr_cont(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) pr_cont(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) id[priv->nr] == pll_desc_id ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) "insmod option" : "autodetected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) kfree(b1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) kfree(b1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) ida_simple_remove(&pll_ida, nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) EXPORT_SYMBOL(dvb_pll_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) dvb_pll_probe(struct i2c_client *client, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct dvb_pll_config *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) unsigned int desc_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) cfg = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) fe = cfg->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) i2c_set_clientdata(client, fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) desc_id = (unsigned int) id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (!dvb_pll_attach(fe, client->addr, client->adapter, desc_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * Unset tuner_ops.release (== dvb_pll_release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * which has been just set in the above dvb_pll_attach(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * because if tuner_ops.release was left defined,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * this module would be 'put' twice on exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * once by dvb_frontend_detach() and another by dvb_module_release().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * dvb_pll_release is instead executed in the i2c driver's .remove(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * keeping dvb_pll_attach untouched for legacy (dvb_attach) drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) fe->ops.tuner_ops.release = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) dev_info(&client->dev, "DVB Simple Tuner attached.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) static int dvb_pll_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct dvb_frontend *fe = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) struct dvb_pll_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ida_simple_remove(&pll_ida, priv->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) dvb_pll_release(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static const struct i2c_device_id dvb_pll_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {"dtt7579", DVB_PLL_THOMSON_DTT7579},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) {"dtt759x", DVB_PLL_THOMSON_DTT759X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {"z201", DVB_PLL_LG_Z201},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {"unknown_1", DVB_PLL_UNKNOWN_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) {"tua6010xs", DVB_PLL_TUA6010XS},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {"env57h1xd5", DVB_PLL_ENV57H1XD5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {"tua6034", DVB_PLL_TUA6034},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {"tda665x", DVB_PLL_TDA665X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {"tded4", DVB_PLL_TDED4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {"tdhu2", DVB_PLL_TDHU2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {"tbmv", DVB_PLL_SAMSUNG_TBMV},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {"sd1878_tda8261", DVB_PLL_PHILIPS_SD1878_TDA8261},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) {"opera1", DVB_PLL_OPERA1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) {"dtos403ih102a", DVB_PLL_SAMSUNG_DTOS403IH102A},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {"tdtc9251dh0", DVB_PLL_SAMSUNG_TDTC9251DH0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {"tbdu18132", DVB_PLL_SAMSUNG_TBDU18132},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {"tbmu24112", DVB_PLL_SAMSUNG_TBMU24112},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) {"tdee4", DVB_PLL_TDEE4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {"dtt7520x", DVB_PLL_THOMSON_DTT7520X},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {"tua6034_friio", DVB_PLL_TUA6034_FRIIO},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {"tda665x_earthpt1", DVB_PLL_TDA665X_EARTH_PT1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) MODULE_DEVICE_TABLE(i2c, dvb_pll_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static struct i2c_driver dvb_pll_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) .name = "dvb_pll",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .probe = dvb_pll_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .remove = dvb_pll_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .id_table = dvb_pll_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) module_i2c_driver(dvb_pll_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) MODULE_DESCRIPTION("dvb pll library");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) MODULE_AUTHOR("Gerd Knorr");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) MODULE_LICENSE("GPL");