1 /* 2 Driver for ST STB6000 DVBS Silicon tuner 3 4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) 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 23 #include <linux/slab.h> 24 #include <linux/module.h> 25 #include <linux/dvb/frontend.h> 26 #include <asm/types.h> 27 28 #include "stb6000.h" 29 30 static int debug; 31 #define dprintk(args...) \ 32 do { \ 33 if (debug) \ 34 printk(KERN_DEBUG "stb6000: " args); \ 35 } while (0) 36 37 struct stb6000_priv { 38 /* i2c details */ 39 int i2c_address; 40 struct i2c_adapter *i2c; 41 u32 frequency; 42 }; 43 44 static void stb6000_release(struct dvb_frontend *fe) 45 { 46 kfree(fe->tuner_priv); 47 fe->tuner_priv = NULL; 48 } 49 50 static int stb6000_sleep(struct dvb_frontend *fe) 51 { 52 struct stb6000_priv *priv = fe->tuner_priv; 53 int ret; 54 u8 buf[] = { 10, 0 }; 55 struct i2c_msg msg = { 56 .addr = priv->i2c_address, 57 .flags = 0, 58 .buf = buf, 59 .len = 2 60 }; 61 62 dprintk("%s:\n", __func__); 63 64 if (fe->ops.i2c_gate_ctrl) 65 fe->ops.i2c_gate_ctrl(fe, 1); 66 67 ret = i2c_transfer(priv->i2c, &msg, 1); 68 if (ret != 1) 69 dprintk("%s: i2c error\n", __func__); 70 71 if (fe->ops.i2c_gate_ctrl) 72 fe->ops.i2c_gate_ctrl(fe, 0); 73 74 return (ret == 1) ? 0 : ret; 75 } 76 77 static int stb6000_set_params(struct dvb_frontend *fe) 78 { 79 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 80 struct stb6000_priv *priv = fe->tuner_priv; 81 unsigned int n, m; 82 int ret; 83 u32 freq_mhz; 84 int bandwidth; 85 u8 buf[12]; 86 struct i2c_msg msg = { 87 .addr = priv->i2c_address, 88 .flags = 0, 89 .buf = buf, 90 .len = 12 91 }; 92 93 dprintk("%s:\n", __func__); 94 95 freq_mhz = p->frequency / 1000; 96 bandwidth = p->symbol_rate / 1000000; 97 98 if (bandwidth > 31) 99 bandwidth = 31; 100 101 if ((freq_mhz > 949) && (freq_mhz < 2151)) { 102 buf[0] = 0x01; 103 buf[1] = 0xac; 104 if (freq_mhz < 1950) 105 buf[1] = 0xaa; 106 if (freq_mhz < 1800) 107 buf[1] = 0xa8; 108 if (freq_mhz < 1650) 109 buf[1] = 0xa6; 110 if (freq_mhz < 1530) 111 buf[1] = 0xa5; 112 if (freq_mhz < 1470) 113 buf[1] = 0xa4; 114 if (freq_mhz < 1370) 115 buf[1] = 0xa2; 116 if (freq_mhz < 1300) 117 buf[1] = 0xa1; 118 if (freq_mhz < 1200) 119 buf[1] = 0xa0; 120 if (freq_mhz < 1075) 121 buf[1] = 0xbc; 122 if (freq_mhz < 1000) 123 buf[1] = 0xba; 124 if (freq_mhz < 1075) { 125 n = freq_mhz / 8; /* vco=lo*4 */ 126 m = 2; 127 } else { 128 n = freq_mhz / 16; /* vco=lo*2 */ 129 m = 1; 130 } 131 buf[2] = n >> 1; 132 buf[3] = (unsigned char)(((n & 1) << 7) | 133 (m * freq_mhz - n * 16) | 0x60); 134 buf[4] = 0x04; 135 buf[5] = 0x0e; 136 137 buf[6] = (unsigned char)(bandwidth); 138 139 buf[7] = 0xd8; 140 buf[8] = 0xd0; 141 buf[9] = 0x50; 142 buf[10] = 0xeb; 143 buf[11] = 0x4f; 144 145 if (fe->ops.i2c_gate_ctrl) 146 fe->ops.i2c_gate_ctrl(fe, 1); 147 148 ret = i2c_transfer(priv->i2c, &msg, 1); 149 if (ret != 1) 150 dprintk("%s: i2c error\n", __func__); 151 152 udelay(10); 153 if (fe->ops.i2c_gate_ctrl) 154 fe->ops.i2c_gate_ctrl(fe, 0); 155 156 buf[0] = 0x07; 157 buf[1] = 0xdf; 158 buf[2] = 0xd0; 159 buf[3] = 0x50; 160 buf[4] = 0xfb; 161 msg.len = 5; 162 163 if (fe->ops.i2c_gate_ctrl) 164 fe->ops.i2c_gate_ctrl(fe, 1); 165 166 ret = i2c_transfer(priv->i2c, &msg, 1); 167 if (ret != 1) 168 dprintk("%s: i2c error\n", __func__); 169 170 udelay(10); 171 if (fe->ops.i2c_gate_ctrl) 172 fe->ops.i2c_gate_ctrl(fe, 0); 173 174 priv->frequency = freq_mhz * 1000; 175 176 return (ret == 1) ? 0 : ret; 177 } 178 return -1; 179 } 180 181 static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency) 182 { 183 struct stb6000_priv *priv = fe->tuner_priv; 184 *frequency = priv->frequency; 185 return 0; 186 } 187 188 static const struct dvb_tuner_ops stb6000_tuner_ops = { 189 .info = { 190 .name = "ST STB6000", 191 .frequency_min_hz = 950 * MHz, 192 .frequency_max_hz = 2150 * MHz 193 }, 194 .release = stb6000_release, 195 .sleep = stb6000_sleep, 196 .set_params = stb6000_set_params, 197 .get_frequency = stb6000_get_frequency, 198 }; 199 200 struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, 201 struct i2c_adapter *i2c) 202 { 203 struct stb6000_priv *priv = NULL; 204 u8 b0[] = { 0 }; 205 u8 b1[] = { 0, 0 }; 206 struct i2c_msg msg[2] = { 207 { 208 .addr = addr, 209 .flags = 0, 210 .buf = b0, 211 .len = 0 212 }, { 213 .addr = addr, 214 .flags = I2C_M_RD, 215 .buf = b1, 216 .len = 2 217 } 218 }; 219 int ret; 220 221 dprintk("%s:\n", __func__); 222 223 if (fe->ops.i2c_gate_ctrl) 224 fe->ops.i2c_gate_ctrl(fe, 1); 225 226 /* is some i2c device here ? */ 227 ret = i2c_transfer(i2c, msg, 2); 228 if (fe->ops.i2c_gate_ctrl) 229 fe->ops.i2c_gate_ctrl(fe, 0); 230 231 if (ret != 2) 232 return NULL; 233 234 priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL); 235 if (priv == NULL) 236 return NULL; 237 238 priv->i2c_address = addr; 239 priv->i2c = i2c; 240 241 memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops, 242 sizeof(struct dvb_tuner_ops)); 243 244 fe->tuner_priv = priv; 245 246 return fe; 247 } 248 EXPORT_SYMBOL(stb6000_attach); 249 250 module_param(debug, int, 0644); 251 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 252 253 MODULE_DESCRIPTION("DVB STB6000 driver"); 254 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>"); 255 MODULE_LICENSE("GPL"); 256