Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

V4L/DVB (12461): Add ce5039(zl10039) tuner support.

The code from Jan D. Louw with some minor changes.
http://article.gmane.org/gmane.linux.drivers.dvb/38163
Tested with TeVii S630 DVB-S USB card by me (Igor)

Signed-off-by: Igor M. Liplianin <liplianin@me.by>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Igor M. Liplianin and committed by
Mauro Carvalho Chehab
2ccf5a99 3040b043

+356
+7
drivers/media/dvb/frontends/Kconfig
··· 81 81 help 82 82 A DVB-S tuner module. Say Y when you want to support this frontend. 83 83 84 + config DVB_ZL10039 85 + tristate "Zarlink ZL10039 silicon tuner" 86 + depends on DVB_CORE && I2C 87 + default m if DVB_FE_CUSTOMISE 88 + help 89 + A DVB-S tuner module. Say Y when you want to support this frontend. 90 + 84 91 config DVB_S5H1420 85 92 tristate "Samsung S5H1420 based" 86 93 depends on DVB_CORE && I2C
+1
drivers/media/dvb/frontends/Makefile
··· 31 31 obj-$(CONFIG_DVB_NXT6000) += nxt6000.o 32 32 obj-$(CONFIG_DVB_MT352) += mt352.o 33 33 obj-$(CONFIG_DVB_ZL10036) += zl10036.o 34 + obj-$(CONFIG_DVB_ZL10039) += zl10039.o 34 35 obj-$(CONFIG_DVB_ZL10353) += zl10353.o 35 36 obj-$(CONFIG_DVB_CX22702) += cx22702.o 36 37 obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
+308
drivers/media/dvb/frontends/zl10039.c
··· 1 + /* 2 + * Driver for Zarlink ZL10039 DVB-S tuner 3 + * 4 + * Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/init.h> 24 + #include <linux/string.h> 25 + #include <linux/slab.h> 26 + #include <linux/dvb/frontend.h> 27 + 28 + #include "dvb_frontend.h" 29 + #include "zl10039.h" 30 + 31 + static int debug; 32 + 33 + #define dprintk(args...) \ 34 + do { \ 35 + if (debug) \ 36 + printk(KERN_DEBUG args); \ 37 + } while (0) 38 + 39 + enum zl10039_model_id { 40 + ID_ZL10039 = 1 41 + }; 42 + 43 + struct zl10039_state { 44 + struct i2c_adapter *i2c; 45 + u8 i2c_addr; 46 + u8 id; 47 + }; 48 + 49 + enum zl10039_reg_addr { 50 + PLL0 = 0, 51 + PLL1, 52 + PLL2, 53 + PLL3, 54 + RFFE, 55 + BASE0, 56 + BASE1, 57 + BASE2, 58 + LO0, 59 + LO1, 60 + LO2, 61 + LO3, 62 + LO4, 63 + LO5, 64 + LO6, 65 + GENERAL 66 + }; 67 + 68 + static int zl10039_read(const struct zl10039_state *state, 69 + const enum zl10039_reg_addr reg, u8 *buf, 70 + const size_t count) 71 + { 72 + u8 regbuf[] = { reg }; 73 + struct i2c_msg msg[] = { 74 + {/* Write register address */ 75 + .addr = state->i2c_addr, 76 + .flags = 0, 77 + .buf = regbuf, 78 + .len = 1, 79 + }, {/* Read count bytes */ 80 + .addr = state->i2c_addr, 81 + .flags = I2C_M_RD, 82 + .buf = buf, 83 + .len = count, 84 + }, 85 + }; 86 + 87 + dprintk("%s\n", __func__); 88 + 89 + if (i2c_transfer(state->i2c, msg, 2) != 2) { 90 + dprintk("%s: i2c read error\n", __func__); 91 + return -EREMOTEIO; 92 + } 93 + 94 + return 0; /* Success */ 95 + } 96 + 97 + static int zl10039_write(struct zl10039_state *state, 98 + const enum zl10039_reg_addr reg, const u8 *src, 99 + const size_t count) 100 + { 101 + u8 buf[count + 1]; 102 + struct i2c_msg msg = { 103 + .addr = state->i2c_addr, 104 + .flags = 0, 105 + .buf = buf, 106 + .len = count + 1, 107 + }; 108 + 109 + dprintk("%s\n", __func__); 110 + /* Write register address and data in one go */ 111 + buf[0] = reg; 112 + memcpy(&buf[1], src, count); 113 + if (i2c_transfer(state->i2c, &msg, 1) != 1) { 114 + dprintk("%s: i2c write error\n", __func__); 115 + return -EREMOTEIO; 116 + } 117 + 118 + return 0; /* Success */ 119 + } 120 + 121 + static inline int zl10039_readreg(struct zl10039_state *state, 122 + const enum zl10039_reg_addr reg, u8 *val) 123 + { 124 + return zl10039_read(state, reg, val, 1); 125 + } 126 + 127 + static inline int zl10039_writereg(struct zl10039_state *state, 128 + const enum zl10039_reg_addr reg, 129 + const u8 val) 130 + { 131 + return zl10039_write(state, reg, &val, 1); 132 + } 133 + 134 + static int zl10039_init(struct dvb_frontend *fe) 135 + { 136 + struct zl10039_state *state = fe->tuner_priv; 137 + int ret; 138 + 139 + dprintk("%s\n", __func__); 140 + if (fe->ops.i2c_gate_ctrl) 141 + fe->ops.i2c_gate_ctrl(fe, 1); 142 + /* Reset logic */ 143 + ret = zl10039_writereg(state, GENERAL, 0x40); 144 + if (ret < 0) { 145 + dprintk("Note: i2c write error normal when resetting the " 146 + "tuner\n"); 147 + } 148 + /* Wake up */ 149 + ret = zl10039_writereg(state, GENERAL, 0x01); 150 + if (ret < 0) { 151 + dprintk("Tuner power up failed\n"); 152 + return ret; 153 + } 154 + if (fe->ops.i2c_gate_ctrl) 155 + fe->ops.i2c_gate_ctrl(fe, 0); 156 + 157 + return 0; 158 + } 159 + 160 + static int zl10039_sleep(struct dvb_frontend *fe) 161 + { 162 + struct zl10039_state *state = fe->tuner_priv; 163 + int ret; 164 + 165 + dprintk("%s\n", __func__); 166 + if (fe->ops.i2c_gate_ctrl) 167 + fe->ops.i2c_gate_ctrl(fe, 1); 168 + ret = zl10039_writereg(state, GENERAL, 0x80); 169 + if (ret < 0) { 170 + dprintk("Tuner sleep failed\n"); 171 + return ret; 172 + } 173 + if (fe->ops.i2c_gate_ctrl) 174 + fe->ops.i2c_gate_ctrl(fe, 0); 175 + 176 + return 0; 177 + } 178 + 179 + static int zl10039_set_params(struct dvb_frontend *fe, 180 + struct dvb_frontend_parameters *params) 181 + { 182 + struct zl10039_state *state = fe->tuner_priv; 183 + u8 buf[6]; 184 + u8 bf; 185 + u32 fbw; 186 + u32 div; 187 + int ret; 188 + 189 + dprintk("%s\n", __func__); 190 + dprintk("Set frequency = %d, symbol rate = %d\n", 191 + params->frequency, params->u.qpsk.symbol_rate); 192 + 193 + /* Assumed 10.111 MHz crystal oscillator */ 194 + /* Cancelled num/den 80 to prevent overflow */ 195 + div = (params->frequency * 1000) / 126387; 196 + fbw = (params->u.qpsk.symbol_rate * 27) / 32000; 197 + /* Cancelled num/den 10 to prevent overflow */ 198 + bf = ((fbw * 5088) / 1011100) - 1; 199 + 200 + /*PLL divider*/ 201 + buf[0] = (div >> 8) & 0x7f; 202 + buf[1] = (div >> 0) & 0xff; 203 + /*Reference divider*/ 204 + /* Select reference ratio of 80 */ 205 + buf[2] = 0x1D; 206 + /*PLL test modes*/ 207 + buf[3] = 0x40; 208 + /*RF Control register*/ 209 + buf[4] = 0x6E; /* Bypass enable */ 210 + /*Baseband filter cutoff */ 211 + buf[5] = bf; 212 + 213 + /* Open i2c gate */ 214 + if (fe->ops.i2c_gate_ctrl) 215 + fe->ops.i2c_gate_ctrl(fe, 1); 216 + /* BR = 10, Enable filter adjustment */ 217 + ret = zl10039_writereg(state, BASE1, 0x0A); 218 + if (ret < 0) 219 + goto error; 220 + /* Write new config values */ 221 + ret = zl10039_write(state, PLL0, buf, sizeof(buf)); 222 + if (ret < 0) 223 + goto error; 224 + /* BR = 10, Disable filter adjustment */ 225 + ret = zl10039_writereg(state, BASE1, 0x6A); 226 + if (ret < 0) 227 + goto error; 228 + 229 + /* Close i2c gate */ 230 + if (fe->ops.i2c_gate_ctrl) 231 + fe->ops.i2c_gate_ctrl(fe, 0); 232 + return 0; 233 + error: 234 + dprintk("Error setting tuner\n"); 235 + return ret; 236 + } 237 + 238 + static int zl10039_release(struct dvb_frontend *fe) 239 + { 240 + struct zl10039_state *state = fe->tuner_priv; 241 + 242 + dprintk("%s\n", __func__); 243 + kfree(state); 244 + fe->tuner_priv = NULL; 245 + return 0; 246 + } 247 + 248 + static struct dvb_tuner_ops zl10039_ops = { 249 + .release = zl10039_release, 250 + .init = zl10039_init, 251 + .sleep = zl10039_sleep, 252 + .set_params = zl10039_set_params, 253 + }; 254 + 255 + struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, 256 + u8 i2c_addr, struct i2c_adapter *i2c) 257 + { 258 + struct zl10039_state *state = NULL; 259 + 260 + dprintk("%s\n", __func__); 261 + state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL); 262 + if (state == NULL) 263 + goto error; 264 + 265 + state->i2c = i2c; 266 + state->i2c_addr = i2c_addr; 267 + 268 + /* Open i2c gate */ 269 + if (fe->ops.i2c_gate_ctrl) 270 + fe->ops.i2c_gate_ctrl(fe, 1); 271 + /* check if this is a valid tuner */ 272 + if (zl10039_readreg(state, GENERAL, &state->id) < 0) { 273 + /* Close i2c gate */ 274 + if (fe->ops.i2c_gate_ctrl) 275 + fe->ops.i2c_gate_ctrl(fe, 0); 276 + goto error; 277 + } 278 + /* Close i2c gate */ 279 + if (fe->ops.i2c_gate_ctrl) 280 + fe->ops.i2c_gate_ctrl(fe, 0); 281 + 282 + state->id = state->id & 0x0f; 283 + switch (state->id) { 284 + case ID_ZL10039: 285 + strcpy(fe->ops.tuner_ops.info.name, 286 + "Zarlink ZL10039 DVB-S tuner"); 287 + break; 288 + default: 289 + dprintk("Chip ID=%x does not match a known type\n", state->id); 290 + break; 291 + goto error; 292 + } 293 + 294 + memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops)); 295 + fe->tuner_priv = state; 296 + dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr); 297 + return fe; 298 + error: 299 + kfree(state); 300 + return NULL; 301 + } 302 + EXPORT_SYMBOL(zl10039_attach); 303 + 304 + module_param(debug, int, 0644); 305 + MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 306 + MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver"); 307 + MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>"); 308 + MODULE_LICENSE("GPL");
+40
drivers/media/dvb/frontends/zl10039.h
··· 1 + /* 2 + Driver for Zarlink ZL10039 DVB-S tuner 3 + 4 + Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za> 5 + 6 + This program is free software; you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation; either version 2 of the License, or 9 + (at your option) any later version. 10 + 11 + This program is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + 15 + GNU General Public License for more details. 16 + 17 + You should have received a copy of the GNU General Public License 18 + along with this program; if not, write to the Free Software 19 + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 + */ 21 + 22 + #ifndef ZL10039_H 23 + #define ZL10039_H 24 + 25 + #if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \ 26 + && defined(MODULE)) 27 + struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, 28 + u8 i2c_addr, 29 + struct i2c_adapter *i2c); 30 + #else 31 + static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, 32 + u8 i2c_addr, 33 + struct i2c_adapter *i2c) 34 + { 35 + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 36 + return NULL; 37 + } 38 + #endif /* CONFIG_DVB_ZL10039 */ 39 + 40 + #endif /* ZL10039_H */