Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for Zarlink ZL10039 DVB-S tuner
0004  *
0005  *  Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/init.h>
0010 #include <linux/string.h>
0011 #include <linux/slab.h>
0012 #include <linux/dvb/frontend.h>
0013 
0014 #include <media/dvb_frontend.h>
0015 #include "zl10039.h"
0016 
0017 static int debug;
0018 
0019 /* Max transfer size done by I2C transfer functions */
0020 #define MAX_XFER_SIZE  64
0021 
0022 #define dprintk(args...) \
0023     do { \
0024         if (debug) \
0025             printk(KERN_DEBUG args); \
0026     } while (0)
0027 
0028 enum zl10039_model_id {
0029     ID_ZL10039 = 1
0030 };
0031 
0032 struct zl10039_state {
0033     struct i2c_adapter *i2c;
0034     u8 i2c_addr;
0035     u8 id;
0036 };
0037 
0038 enum zl10039_reg_addr {
0039     PLL0 = 0,
0040     PLL1,
0041     PLL2,
0042     PLL3,
0043     RFFE,
0044     BASE0,
0045     BASE1,
0046     BASE2,
0047     LO0,
0048     LO1,
0049     LO2,
0050     LO3,
0051     LO4,
0052     LO5,
0053     LO6,
0054     GENERAL
0055 };
0056 
0057 static int zl10039_read(const struct zl10039_state *state,
0058             const enum zl10039_reg_addr reg, u8 *buf,
0059             const size_t count)
0060 {
0061     u8 regbuf[] = { reg };
0062     struct i2c_msg msg[] = {
0063         {/* Write register address */
0064             .addr = state->i2c_addr,
0065             .flags = 0,
0066             .buf = regbuf,
0067             .len = 1,
0068         }, {/* Read count bytes */
0069             .addr = state->i2c_addr,
0070             .flags = I2C_M_RD,
0071             .buf = buf,
0072             .len = count,
0073         },
0074     };
0075 
0076     dprintk("%s\n", __func__);
0077 
0078     if (i2c_transfer(state->i2c, msg, 2) != 2) {
0079         dprintk("%s: i2c read error\n", __func__);
0080         return -EREMOTEIO;
0081     }
0082 
0083     return 0; /* Success */
0084 }
0085 
0086 static int zl10039_write(struct zl10039_state *state,
0087             const enum zl10039_reg_addr reg, const u8 *src,
0088             const size_t count)
0089 {
0090     u8 buf[MAX_XFER_SIZE];
0091     struct i2c_msg msg = {
0092         .addr = state->i2c_addr,
0093         .flags = 0,
0094         .buf = buf,
0095         .len = count + 1,
0096     };
0097 
0098     if (1 + count > sizeof(buf)) {
0099         printk(KERN_WARNING
0100                "%s: i2c wr reg=%04x: len=%zu is too big!\n",
0101                KBUILD_MODNAME, reg, count);
0102         return -EINVAL;
0103     }
0104 
0105     dprintk("%s\n", __func__);
0106     /* Write register address and data in one go */
0107     buf[0] = reg;
0108     memcpy(&buf[1], src, count);
0109     if (i2c_transfer(state->i2c, &msg, 1) != 1) {
0110         dprintk("%s: i2c write error\n", __func__);
0111         return -EREMOTEIO;
0112     }
0113 
0114     return 0; /* Success */
0115 }
0116 
0117 static inline int zl10039_readreg(struct zl10039_state *state,
0118                 const enum zl10039_reg_addr reg, u8 *val)
0119 {
0120     return zl10039_read(state, reg, val, 1);
0121 }
0122 
0123 static inline int zl10039_writereg(struct zl10039_state *state,
0124                 const enum zl10039_reg_addr reg,
0125                 const u8 val)
0126 {
0127     const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
0128 
0129     return zl10039_write(state, reg, &tmp, 1);
0130 }
0131 
0132 static int zl10039_init(struct dvb_frontend *fe)
0133 {
0134     struct zl10039_state *state = fe->tuner_priv;
0135     int ret;
0136 
0137     dprintk("%s\n", __func__);
0138     if (fe->ops.i2c_gate_ctrl)
0139         fe->ops.i2c_gate_ctrl(fe, 1);
0140     /* Reset logic */
0141     ret = zl10039_writereg(state, GENERAL, 0x40);
0142     if (ret < 0) {
0143         dprintk("Note: i2c write error normal when resetting the tuner\n");
0144     }
0145     /* Wake up */
0146     ret = zl10039_writereg(state, GENERAL, 0x01);
0147     if (ret < 0) {
0148         dprintk("Tuner power up failed\n");
0149         return ret;
0150     }
0151     if (fe->ops.i2c_gate_ctrl)
0152         fe->ops.i2c_gate_ctrl(fe, 0);
0153 
0154     return 0;
0155 }
0156 
0157 static int zl10039_sleep(struct dvb_frontend *fe)
0158 {
0159     struct zl10039_state *state = fe->tuner_priv;
0160     int ret;
0161 
0162     dprintk("%s\n", __func__);
0163     if (fe->ops.i2c_gate_ctrl)
0164         fe->ops.i2c_gate_ctrl(fe, 1);
0165     ret = zl10039_writereg(state, GENERAL, 0x80);
0166     if (ret < 0) {
0167         dprintk("Tuner sleep failed\n");
0168         return ret;
0169     }
0170     if (fe->ops.i2c_gate_ctrl)
0171         fe->ops.i2c_gate_ctrl(fe, 0);
0172 
0173     return 0;
0174 }
0175 
0176 static int zl10039_set_params(struct dvb_frontend *fe)
0177 {
0178     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0179     struct zl10039_state *state = fe->tuner_priv;
0180     u8 buf[6];
0181     u8 bf;
0182     u32 fbw;
0183     u32 div;
0184     int ret;
0185 
0186     dprintk("%s\n", __func__);
0187     dprintk("Set frequency = %d, symbol rate = %d\n",
0188             c->frequency, c->symbol_rate);
0189 
0190     /* Assumed 10.111 MHz crystal oscillator */
0191     /* Cancelled num/den 80 to prevent overflow */
0192     div = (c->frequency * 1000) / 126387;
0193     fbw = (c->symbol_rate * 27) / 32000;
0194     /* Cancelled num/den 10 to prevent overflow */
0195     bf = ((fbw * 5088) / 1011100) - 1;
0196 
0197     /*PLL divider*/
0198     buf[0] = (div >> 8) & 0x7f;
0199     buf[1] = (div >> 0) & 0xff;
0200     /*Reference divider*/
0201     /* Select reference ratio of 80 */
0202     buf[2] = 0x1D;
0203     /*PLL test modes*/
0204     buf[3] = 0x40;
0205     /*RF Control register*/
0206     buf[4] = 0x6E; /* Bypass enable */
0207     /*Baseband filter cutoff */
0208     buf[5] = bf;
0209 
0210     /* Open i2c gate */
0211     if (fe->ops.i2c_gate_ctrl)
0212         fe->ops.i2c_gate_ctrl(fe, 1);
0213     /* BR = 10, Enable filter adjustment */
0214     ret = zl10039_writereg(state, BASE1, 0x0A);
0215     if (ret < 0)
0216         goto error;
0217     /* Write new config values */
0218     ret = zl10039_write(state, PLL0, buf, sizeof(buf));
0219     if (ret < 0)
0220         goto error;
0221     /* BR = 10, Disable filter adjustment */
0222     ret = zl10039_writereg(state, BASE1, 0x6A);
0223     if (ret < 0)
0224         goto error;
0225 
0226     /* Close i2c gate */
0227     if (fe->ops.i2c_gate_ctrl)
0228         fe->ops.i2c_gate_ctrl(fe, 0);
0229     return 0;
0230 error:
0231     dprintk("Error setting tuner\n");
0232     return ret;
0233 }
0234 
0235 static void zl10039_release(struct dvb_frontend *fe)
0236 {
0237     struct zl10039_state *state = fe->tuner_priv;
0238 
0239     dprintk("%s\n", __func__);
0240     kfree(state);
0241     fe->tuner_priv = NULL;
0242 }
0243 
0244 static const struct dvb_tuner_ops zl10039_ops = {
0245     .release = zl10039_release,
0246     .init = zl10039_init,
0247     .sleep = zl10039_sleep,
0248     .set_params = zl10039_set_params,
0249 };
0250 
0251 struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
0252         u8 i2c_addr, struct i2c_adapter *i2c)
0253 {
0254     struct zl10039_state *state = NULL;
0255 
0256     dprintk("%s\n", __func__);
0257     state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
0258     if (state == NULL)
0259         goto error;
0260 
0261     state->i2c = i2c;
0262     state->i2c_addr = i2c_addr;
0263 
0264     /* Open i2c gate */
0265     if (fe->ops.i2c_gate_ctrl)
0266         fe->ops.i2c_gate_ctrl(fe, 1);
0267     /* check if this is a valid tuner */
0268     if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
0269         /* Close i2c gate */
0270         if (fe->ops.i2c_gate_ctrl)
0271             fe->ops.i2c_gate_ctrl(fe, 0);
0272         goto error;
0273     }
0274     /* Close i2c gate */
0275     if (fe->ops.i2c_gate_ctrl)
0276         fe->ops.i2c_gate_ctrl(fe, 0);
0277 
0278     state->id = state->id & 0x0f;
0279     switch (state->id) {
0280     case ID_ZL10039:
0281         strscpy(fe->ops.tuner_ops.info.name,
0282             "Zarlink ZL10039 DVB-S tuner",
0283             sizeof(fe->ops.tuner_ops.info.name));
0284         break;
0285     default:
0286         dprintk("Chip ID=%x does not match a known type\n", state->id);
0287         goto error;
0288     }
0289 
0290     memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
0291     fe->tuner_priv = state;
0292     dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
0293     return fe;
0294 error:
0295     kfree(state);
0296     return NULL;
0297 }
0298 EXPORT_SYMBOL(zl10039_attach);
0299 
0300 module_param(debug, int, 0644);
0301 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0302 MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
0303 MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
0304 MODULE_LICENSE("GPL");