^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");