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