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) // 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)  *  Driver for Zarlink ZL10039 DVB-S tuner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
^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) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/dvb/frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "zl10039.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /* Max transfer size done by I2C transfer functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define MAX_XFER_SIZE  64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define dprintk(args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 			printk(KERN_DEBUG args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) enum zl10039_model_id {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	ID_ZL10039 = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct zl10039_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	u8 i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) enum zl10039_reg_addr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	PLL0 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	PLL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	PLL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	PLL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	RFFE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	BASE0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	BASE1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	BASE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	LO0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	LO1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	LO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	LO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	LO4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	LO5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	LO6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	GENERAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) static int zl10039_read(const struct zl10039_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			const enum zl10039_reg_addr reg, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			const size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u8 regbuf[] = { reg };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		{/* Write register address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 			.addr = state->i2c_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 			.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			.buf = regbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 			.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		}, {/* Read count bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			.addr = state->i2c_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			.flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			.buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			.len = count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (i2c_transfer(state->i2c, msg, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		dprintk("%s: i2c read error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return 0; /* Success */
^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) static int zl10039_write(struct zl10039_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			const enum zl10039_reg_addr reg, const u8 *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			const size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	u8 buf[MAX_XFER_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct i2c_msg msg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		.addr = state->i2c_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		.flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		.buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		.len = count + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	if (1 + count > sizeof(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		       "%s: i2c wr reg=%04x: len=%zu is too big!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		       KBUILD_MODNAME, reg, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	/* Write register address and data in one go */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	buf[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	memcpy(&buf[1], src, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		dprintk("%s: i2c write error\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	return 0; /* Success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline int zl10039_readreg(struct zl10039_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				const enum zl10039_reg_addr reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return zl10039_read(state, reg, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static inline int zl10039_writereg(struct zl10039_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				const enum zl10039_reg_addr reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 				const u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	return zl10039_write(state, reg, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static int zl10039_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	struct zl10039_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* Reset logic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	ret = zl10039_writereg(state, GENERAL, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		dprintk("Note: i2c write error normal when resetting the tuner\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	/* Wake up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	ret = zl10039_writereg(state, GENERAL, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		dprintk("Tuner power up failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int zl10039_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	struct zl10039_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ret = zl10039_writereg(state, GENERAL, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		dprintk("Tuner sleep failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int zl10039_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	struct zl10039_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	u8 buf[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	u8 bf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	u32 fbw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	u32 div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	dprintk("Set frequency = %d, symbol rate = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 			c->frequency, c->symbol_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	/* Assumed 10.111 MHz crystal oscillator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	/* Cancelled num/den 80 to prevent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	div = (c->frequency * 1000) / 126387;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	fbw = (c->symbol_rate * 27) / 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	/* Cancelled num/den 10 to prevent overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	bf = ((fbw * 5088) / 1011100) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/*PLL divider*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	buf[0] = (div >> 8) & 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	buf[1] = (div >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/*Reference divider*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	/* Select reference ratio of 80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	buf[2] = 0x1D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	/*PLL test modes*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	buf[3] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	/*RF Control register*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	buf[4] = 0x6E; /* Bypass enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	/*Baseband filter cutoff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	buf[5] = bf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	/* Open i2c gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* BR = 10, Enable filter adjustment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	ret = zl10039_writereg(state, BASE1, 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	/* Write new config values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	ret = zl10039_write(state, PLL0, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	/* BR = 10, Disable filter adjustment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	ret = zl10039_writereg(state, BASE1, 0x6A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* Close i2c gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	dprintk("Error setting tuner\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return ret;
^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) static void zl10039_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	struct zl10039_state *state = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static const struct dvb_tuner_ops zl10039_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	.release = zl10039_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	.init = zl10039_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	.sleep = zl10039_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	.set_params = zl10039_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		u8 i2c_addr, struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	struct zl10039_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	dprintk("%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (state == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	state->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	state->i2c_addr = i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	/* Open i2c gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	/* check if this is a valid tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		/* Close i2c gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	/* Close i2c gate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	state->id = state->id & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	switch (state->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	case ID_ZL10039:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		strscpy(fe->ops.tuner_ops.info.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			"Zarlink ZL10039 DVB-S tuner",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			sizeof(fe->ops.tuner_ops.info.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		dprintk("Chip ID=%x does not match a known type\n", state->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	fe->tuner_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) EXPORT_SYMBOL(zl10039_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) MODULE_LICENSE("GPL");