Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Copyright (C) 2001-5, B2C2 inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@posteo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  This driver is "hard-coded" to be used with the 1st generation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  (Panasonic CT10S) is located here, which is actually wrong. Unless there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *  another device with a BCM3510, this is no problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  The driver works also with QAM64 DVB-C, but had an unreasonable high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  UNC. (Tested with the Air2PC ATSC 1st generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *  You'll need a firmware for this driver in order to get it running. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  called "dvb-fe-bcm3510-01.fw".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * This program is free software; you can redistribute it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * under the terms of the GNU General Public License as published by the Free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Software Foundation; either version 2 of the License, or (at your option)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * This program is distributed in the hope that it will be useful, but WITHOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * You should have received a copy of the GNU General Public License along with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include "bcm3510.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include "bcm3510_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /* Max transfer size done by bcm3510_do_hab_cmd() function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define MAX_XFER_SIZE	128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) struct bcm3510_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct i2c_adapter* i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	const struct bcm3510_config* config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct dvb_frontend frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* demodulator private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct mutex hab_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u8 firmware_loaded:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	unsigned long next_status_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	unsigned long status_check_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct bcm3510_hab_cmd_status1 status1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct bcm3510_hab_cmd_status2 status2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define dprintk(level,x...) if (level & debug) printk(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define dbufout(b,l,m) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	    int i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	    for (i = 0; i < l; i++) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		m("%02x ",b[i]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define deb_info(args...) dprintk(0x01,args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define deb_i2c(args...)  dprintk(0x02,args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define deb_hab(args...)  dprintk(0x04,args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /* transfer functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	u8 b[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	b[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	memcpy(&b[1],buf,len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	deb_i2c("i2c wr %02x: ",reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	dbufout(buf,len,deb_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	deb_i2c("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			__func__, state->config->demod_address, reg,  err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		{ .addr = state->config->demod_address, .flags = 0,        .buf = &reg, .len = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf,  .len = len }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	memset(buf,0,len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			__func__, state->config->demod_address, reg,  err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	deb_i2c("i2c rd %02x: ",reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	dbufout(buf,len,deb_i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	deb_i2c("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	return bcm3510_writebytes(state,reg,&v.raw,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	return bcm3510_readbytes(state,reg,&v->raw,1);
^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) /* Host Access Buffer transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	bcm3510_register_value v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int ret,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	v.HABADR_a6.HABADR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		buf[i] = v.HABDATA_a7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	bcm3510_register_value v,hab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	int ret,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Check if any previous HAB request still needs to be serviced by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * Acquisition Processor before sending new request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (v.HABSTAT_a8.HABR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		deb_info("HAB is running already - clearing it.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		v.HABSTAT_a8.HABR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		bcm3510_writeB(st,0xa8,v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) //		return -EBUSY;
^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) /* Send the start HAB Address (automatically incremented after write of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * HABDATA) and write the HAB Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	hab.HABADR_a6.HABADR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		hab.HABDATA_a7 = buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  * be written) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* Polling method: Wait until the AP finishes processing the HAB request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	t = jiffies + 1*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	while (time_before(jiffies, t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		deb_info("waiting for HAB to complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		if (!v.HABSTAT_a8.HABR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			return 0;
^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) 	deb_info("send_request execution timed out.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	u8 ob[MAX_XFER_SIZE], ib[MAX_XFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	if (ilen + 2 > sizeof(ib)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		deb_hab("do_hab_cmd: ilen=%d is too big!\n", ilen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (olen + 2 > sizeof(ob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		deb_hab("do_hab_cmd: olen=%d is too big!\n", olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ob[0] = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	ob[1] = msgid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	memcpy(&ob[2],obuf,olen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	deb_hab("hab snd: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	dbufout(ob,olen+2,deb_hab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	deb_hab("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (mutex_lock_interruptible(&st->hab_mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		(ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	deb_hab("hab get: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	dbufout(ib,ilen+2,deb_hab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	deb_hab("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	memcpy(ibuf,&ib[2],ilen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	mutex_unlock(&st->hab_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* not needed, we use a semaphore to prevent HAB races */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int bcm3510_is_ap_ready(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	bcm3510_register_value ap,hab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		(ret = bcm3510_readB(st,0xa2,&ap) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		deb_info("AP is busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int bcm3510_bert_reset(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	bcm3510_register_value b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	/* clear residual bit counter TODO  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int bcm3510_refresh_state(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (time_after(jiffies,st->next_status_check)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int bcm3510_read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	bcm3510_refresh_state(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	*status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (st->status1.STATUS1.RECEIVER_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		*status |= FE_HAS_LOCK | FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (st->status1.STATUS1.FEC_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		*status |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (st->status1.STATUS1.OUT_PLL_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	if (*status & FE_HAS_LOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		st->status_check_interval = 1500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	else /* more frequently checks if no lock has been achieved yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		st->status_check_interval = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	deb_info("real_status: %02x\n",*status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	bcm3510_refresh_state(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	*ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	bcm3510_refresh_state(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	*unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	s32 t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	bcm3510_refresh_state(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	t = st->status2.SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (t > 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		t = 190;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	if (t < 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		t = 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	t -= 90;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	t = t * 0xff / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	/* normalize if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	*strength = (t << 8) | t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	bcm3510_refresh_state(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	*snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* tuner frontend programming */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	struct bcm3510_hab_cmd_tune c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* I2C Mode disabled,  set 16 control / Data pairs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	c.length = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	c.clock_width = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  * logic high (as Configuration) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	c.misc = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	c.TUNCTL_state = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	c.ctl_dat[0].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	c.ctl_dat[0].data      = 0x80 | bc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	c.ctl_dat[1].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	c.ctl_dat[1].data      = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	c.ctl_dat[2].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	c.ctl_dat[2].data      = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* control CS0 pin, pulse byte ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	c.ctl_dat[3].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	c.ctl_dat[3].ctrl.clk_off = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	c.ctl_dat[3].ctrl.cs0  = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	c.ctl_dat[3].data      = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) /* PGM_S18 to PGM_S11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	c.ctl_dat[4].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	c.ctl_dat[4].data      = n >> 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) /* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	c.ctl_dat[5].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	c.ctl_dat[5].data      = ((n & 0x7) << 5) | (a >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	c.ctl_dat[6].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	c.ctl_dat[6].data      = (a << 6) & 0xdf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) /* control CS0 pin, pulse byte ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	c.ctl_dat[7].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	c.ctl_dat[7].ctrl.clk_off = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	c.ctl_dat[7].ctrl.cs0  = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	c.ctl_dat[7].data      = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	c.ctl_dat[8].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	c.ctl_dat[8].data      = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	c.ctl_dat[9].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	c.ctl_dat[9].data      = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) /* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	c.ctl_dat[10].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	c.ctl_dat[10].data      = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* pulse byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	c.ctl_dat[11].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	c.ctl_dat[11].ctrl.clk_off = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	c.ctl_dat[11].ctrl.cs1  = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	c.ctl_dat[11].data      = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* PGM_S18 to PGM_S11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	c.ctl_dat[12].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	c.ctl_dat[12].data      = 0x2a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	c.ctl_dat[13].ctrl.size = BITS_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	c.ctl_dat[13].data      = 0x8e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) /* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	c.ctl_dat[14].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	c.ctl_dat[14].data      = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* Pulse Byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	c.ctl_dat[15].ctrl.size = BITS_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	c.ctl_dat[15].ctrl.clk_off = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	c.ctl_dat[15].ctrl.cs1  = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	c.ctl_dat[15].data      = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	u8 bc,a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	u16 n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	s32 YIntercept,Tfvco1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	freq /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	deb_info("%dkHz:",freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	/* set Band Switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (freq <= 168000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		bc = 0x1c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	else if (freq <= 378000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		bc = 0x2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		bc = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (freq >= 470000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		freq -= 470001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		YIntercept = 18805;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	} else if (freq >= 90000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		freq -= 90001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		YIntercept = 15005;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	} else if (freq >= 76000){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		freq -= 76001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		YIntercept = 14865;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		freq -= 54001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		YIntercept = 14645;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	n = Tfvco1 >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	a = Tfvco1 & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	if (n >= 16 && n <= 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		return bcm3510_tuner_cmd(st,bc,n,a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int bcm3510_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	struct bcm3510_hab_cmd_ext_acquire cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct bcm3510_hab_cmd_bert_control bert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	memset(&cmd,0,sizeof(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	switch (c->modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 			cmd.ACQUIRE0.MODE = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			cmd.ACQUIRE1.SYM_RATE = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 			cmd.ACQUIRE1.IF_FREQ = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			cmd.ACQUIRE0.MODE = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			cmd.ACQUIRE1.SYM_RATE = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 			cmd.ACQUIRE1.IF_FREQ = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			cmd.ACQUIRE0.MODE = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		case QAM_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			cmd.ACQUIRE0.MODE = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 			cmd.ACQUIRE0.MODE = 0x5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		case QAM_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			cmd.ACQUIRE0.MODE = 0x6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		case QAM_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			cmd.ACQUIRE0.MODE = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			cmd.ACQUIRE0.MODE = 0x8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			cmd.ACQUIRE1.SYM_RATE = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			cmd.ACQUIRE1.IF_FREQ = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		case VSB_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			cmd.ACQUIRE0.MODE = 0x9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			cmd.ACQUIRE1.SYM_RATE = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			cmd.ACQUIRE1.IF_FREQ = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	cmd.ACQUIRE0.OFFSET = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	cmd.ACQUIRE0.NTSCSWEEP = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	cmd.ACQUIRE0.FA = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	cmd.ACQUIRE0.BW = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /*	if (enableOffset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		cmd.IF_OFFSET0 = xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		cmd.IF_OFFSET1 = xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		cmd.SYM_OFFSET0 = xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		cmd.SYM_OFFSET1 = xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		if (enableNtscSweep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 			cmd.NTSC_OFFSET0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 			cmd.NTSC_OFFSET1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	} */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* doing it with different MSGIDs, data book and source differs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	bert.BE = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	bert.unused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	bcm3510_bert_reset(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	ret = bcm3510_set_freq(st, c->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	memset(&st->status1,0,sizeof(st->status1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	memset(&st->status2,0,sizeof(st->status2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	st->status_check_interval = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) /* Give the AP some time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int bcm3510_sleep(struct dvb_frontend* fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	s->min_delay_ms = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	s->step_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	s->max_drift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void bcm3510_release(struct dvb_frontend* fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	struct bcm3510_state* state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) /* firmware download:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)  * firmware file is build up like this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)  * 16bit addr, 16bit length, 8byte of length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) #define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 			     u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	int ret = 0,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	bcm3510_register_value vH, vL,vD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	vH.MADRH_a9 = addr >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	vL.MADRL_aa = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		vD.MDATA_ab = b[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int bcm3510_download_firmware(struct dvb_frontend* fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	u16 addr,len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	const u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	int ret,i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	deb_info("requesting firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	deb_info("got firmware: %zu\n", fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	b = fw->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	for (i = 0; i < fw->size;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		addr = le16_to_cpu(*((__le16 *)&b[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		len  = le16_to_cpu(*((__le16 *)&b[i+2]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 		if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			err("firmware download failed: %d\n",ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 		i += 4 + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	deb_info("firmware download successfully completed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int bcm3510_check_firmware_version(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	struct bcm3510_hab_cmd_get_version_info ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 		ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 		ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 		ver.demod_version  == BCM3510_DEF_DEMOD_VERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	deb_info("version check failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) /* (un)resetting the AP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int bcm3510_reset(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	unsigned long  t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	bcm3510_register_value v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	t = jiffies + 3*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 	while (time_before(jiffies, t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		if (v.APSTAT1_a2.RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	deb_info("reset timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static int bcm3510_clear_reset(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	bcm3510_register_value v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	unsigned long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	v.raw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	t = jiffies + 3*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	while (time_before(jiffies, t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 		if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		/* verify that reset is cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		if (!v.APSTAT1_a2.RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	deb_info("reset clear timed out\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static int bcm3510_init_cold(struct bcm3510_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	bcm3510_register_value v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	/* read Acquisation Processor status register and check it is not in RUN mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	if (v.APSTAT1_a2.RUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		deb_info("AP is already running - firmware already loaded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	deb_info("reset?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	if ((ret = bcm3510_reset(st)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	deb_info("tristate?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	/* tri-state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	v.TSTCTL_2e.CTL = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	deb_info("firmware?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		(ret = bcm3510_clear_reset(st)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	/* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int bcm3510_init(struct dvb_frontend* fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	struct bcm3510_state* st = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	bcm3510_register_value j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	struct bcm3510_hab_cmd_set_agc c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	deb_info("JDEC: %02x\n",j.raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	switch (j.JDEC_ca.JDEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 		case JDEC_WAIT_AT_RAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 			deb_info("attempting to download firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 			if ((ret = bcm3510_init_cold(st)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		case JDEC_EEPROM_LOAD_WAIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 			deb_info("firmware is loaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 			bcm3510_check_firmware_version(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 			return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	memset(&c,0,1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	c.SEL = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static const struct dvb_frontend_ops bcm3510_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 				   struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	struct bcm3510_state* state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	bcm3510_register_value v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	/* allocate memory for the internal state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	/* setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	state->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	state->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	/* create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	state->frontend.demodulator_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	mutex_init(&state->hab_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		(v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0))   /* warm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	bcm3510_reset(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	return &state->frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) EXPORT_SYMBOL(bcm3510_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static const struct dvb_frontend_ops bcm3510_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	.delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	.info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		.name = "Broadcom BCM3510 VSB/QAM frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		.frequency_min_hz =  54 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 		.frequency_max_hz = 803 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		.caps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 			FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 			FE_CAN_8VSB | FE_CAN_16VSB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	.release = bcm3510_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	.init = bcm3510_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 	.sleep = bcm3510_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	.set_frontend = bcm3510_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	.get_tune_settings = bcm3510_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	.read_status = bcm3510_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	.read_ber = bcm3510_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 	.read_signal_strength = bcm3510_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	.read_snr = bcm3510_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	.read_ucblocks = bcm3510_read_unc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) MODULE_LICENSE("GPL");