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

V4L/DVB (6590): Adding support for VHF with MT2266-devices

MT2266 :
- support for VHF
- Minor enhancements

Signed-off-by: Olivier DANET <odanet@caramail.com>
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

authored by

Olivier DANET and committed by
Mauro Carvalho Chehab
542794be 67053a40

+131 -67
+131 -67
drivers/media/dvb/frontends/mt2266.c
··· 38 38 39 39 u32 frequency; 40 40 u32 bandwidth; 41 + u8 band; 41 42 }; 43 + 44 + #define MT2266_VHF 1 45 + #define MT2266_UHF 0 42 46 43 47 /* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */ 44 48 ··· 94 90 } 95 91 96 92 // Initialisation sequences 97 - static u8 mt2266_init1[] = { 98 - REG_TUNE, 99 - 0x00, 0x00, 0x28, 0x00, 0x52, 0x99, 0x3f }; 93 + static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28, 94 + 0x00, 0x52, 0x99, 0x3f }; 100 95 101 96 static u8 mt2266_init2[] = { 102 - 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 103 - 0xd4, 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14, 0x01, 0x01, 0x01, 0x01, 104 - 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff, 0xff, 0x00, 0x77, 0x0f, 0x2d }; 97 + 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4, 98 + 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14, 99 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff, 100 + 0xff, 0x00, 0x77, 0x0f, 0x2d 101 + }; 105 102 106 - static u8 mt2266_init_8mhz[] = { 107 - REG_BANDWIDTH, 108 - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }; 103 + static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22, 104 + 0x22, 0x22, 0x22, 0x22 }; 109 105 110 - static u8 mt2266_init_7mhz[] = { 111 - REG_BANDWIDTH, 112 - 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32 }; 106 + static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32, 107 + 0x32, 0x32, 0x32, 0x32 }; 113 108 114 - static u8 mt2266_init_6mhz[] = { 115 - REG_BANDWIDTH, 116 - 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7 }; 109 + static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7, 110 + 0xa7, 0xa7, 0xa7, 0xa7 }; 111 + 112 + static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64, 113 + 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 }; 114 + 115 + static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5, 116 + 0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f }; 117 117 118 118 #define FREF 30000 // Quartz oscillator 30 MHz 119 119 ··· 130 122 u8 lnaband; 131 123 u8 b[10]; 132 124 int i; 125 + u8 band; 133 126 134 127 priv = fe->tuner_priv; 135 128 136 - mt2266_writereg(priv,0x17,0x6d); 137 - mt2266_writereg(priv,0x1c,0xff); 138 - 139 129 freq = params->frequency / 1000; // Hz -> kHz 130 + if (freq < 470000 && freq > 230000) 131 + return -EINVAL; /* Gap between VHF and UHF bands */ 140 132 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; 141 133 priv->frequency = freq * 1000; 142 - tune=2 * freq * (8192/16) / (FREF/16); 143 134 144 - if (freq <= 495000) lnaband = 0xEE; else 145 - if (freq <= 525000) lnaband = 0xDD; else 146 - if (freq <= 550000) lnaband = 0xCC; else 147 - if (freq <= 580000) lnaband = 0xBB; else 148 - if (freq <= 605000) lnaband = 0xAA; else 149 - if (freq <= 630000) lnaband = 0x99; else 150 - if (freq <= 655000) lnaband = 0x88; else 151 - if (freq <= 685000) lnaband = 0x77; else 152 - if (freq <= 710000) lnaband = 0x66; else 153 - if (freq <= 735000) lnaband = 0x55; else 154 - if (freq <= 765000) lnaband = 0x44; else 155 - if (freq <= 802000) lnaband = 0x33; else 156 - if (freq <= 840000) lnaband = 0x22; else lnaband = 0x11; 135 + tune = 2 * freq * (8192/16) / (FREF/16); 136 + band = (freq < 300000) ? MT2266_VHF : MT2266_UHF; 137 + if (band == MT2266_VHF) 138 + tune *= 2; 157 139 158 - msleep(100); 159 - mt2266_writeregs(priv,(params->u.ofdm.bandwidth==BANDWIDTH_6_MHZ)?mt2266_init_6mhz: 160 - (params->u.ofdm.bandwidth==BANDWIDTH_7_MHZ)?mt2266_init_7mhz: 161 - mt2266_init_8mhz,sizeof(mt2266_init_8mhz)); 140 + switch (params->u.ofdm.bandwidth) { 141 + case BANDWIDTH_6_MHZ: 142 + mt2266_writeregs(priv, mt2266_init_6mhz, 143 + sizeof(mt2266_init_6mhz)); 144 + break; 145 + case BANDWIDTH_7_MHZ: 146 + mt2266_writeregs(priv, mt2266_init_7mhz, 147 + sizeof(mt2266_init_7mhz)); 148 + break; 149 + case BANDWIDTH_8_MHZ: 150 + default: 151 + mt2266_writeregs(priv, mt2266_init_8mhz, 152 + sizeof(mt2266_init_8mhz)); 153 + break; 154 + } 155 + 156 + if (band == MT2266_VHF && priv->band == MT2266_UHF) { 157 + dprintk("Switch from UHF to VHF"); 158 + mt2266_writereg(priv, 0x05, 0x04); 159 + mt2266_writereg(priv, 0x19, 0x61); 160 + mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf)); 161 + } else if (band == MT2266_UHF && priv->band == MT2266_VHF) { 162 + dprintk("Switch from VHF to UHF"); 163 + mt2266_writereg(priv, 0x05, 0x52); 164 + mt2266_writereg(priv, 0x19, 0x61); 165 + mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf)); 166 + } 167 + msleep(10); 168 + 169 + if (freq <= 495000) 170 + lnaband = 0xEE; 171 + else if (freq <= 525000) 172 + lnaband = 0xDD; 173 + else if (freq <= 550000) 174 + lnaband = 0xCC; 175 + else if (freq <= 580000) 176 + lnaband = 0xBB; 177 + else if (freq <= 605000) 178 + lnaband = 0xAA; 179 + else if (freq <= 630000) 180 + lnaband = 0x99; 181 + else if (freq <= 655000) 182 + lnaband = 0x88; 183 + else if (freq <= 685000) 184 + lnaband = 0x77; 185 + else if (freq <= 710000) 186 + lnaband = 0x66; 187 + else if (freq <= 735000) 188 + lnaband = 0x55; 189 + else if (freq <= 765000) 190 + lnaband = 0x44; 191 + else if (freq <= 802000) 192 + lnaband = 0x33; 193 + else if (freq <= 840000) 194 + lnaband = 0x22; 195 + else 196 + lnaband = 0x11; 162 197 163 198 b[0] = REG_TUNE; 164 199 b[1] = (tune >> 8) & 0x1F; ··· 209 158 b[3] = tune >> 13; 210 159 mt2266_writeregs(priv,b,4); 211 160 212 - dprintk("set_parms: tune=%d band=%d",(int)tune,(int)lnaband); 213 - dprintk("set_parms: [1..3]: %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3]); 161 + dprintk("set_parms: tune=%d band=%d %s", 162 + (int) tune, (int) lnaband, 163 + (band == MT2266_UHF) ? "UHF" : "VHF"); 164 + dprintk("set_parms: [1..3]: %2x %2x %2x", 165 + (int) b[1], (int) b[2], (int)b[3]); 214 166 215 - b[0] = 0x05; 216 - b[1] = 0x62; 217 - b[2] = lnaband; 218 - mt2266_writeregs(priv,b,3); 167 + if (band == MT2266_UHF) { 168 + b[0] = 0x05; 169 + b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62; 170 + b[2] = lnaband; 171 + mt2266_writeregs(priv, b, 3); 172 + } 219 173 220 - //Waits for pll lock or timeout 174 + /* Wait for pll lock or timeout */ 221 175 i = 0; 222 176 do { 223 177 mt2266_readreg(priv,REG_LOCK,b); 224 - if ((b[0] & 0x40)==0x40) 178 + if (b[0] & 0x40) 225 179 break; 226 180 msleep(10); 227 181 i++; 228 182 } while (i<10); 229 183 dprintk("Lock when i=%i",(int)i); 184 + 185 + if (band == MT2266_UHF && priv->band == MT2266_VHF) 186 + mt2266_writereg(priv, 0x05, 0x62); 187 + 188 + priv->band = band; 189 + 230 190 return ret; 231 191 } 232 192 233 193 static void mt2266_calibrate(struct mt2266_priv *priv) 234 194 { 235 - mt2266_writereg(priv,0x11,0x03); 236 - mt2266_writereg(priv,0x11,0x01); 237 - 238 - mt2266_writeregs(priv,mt2266_init1,sizeof(mt2266_init1)); 239 - mt2266_writeregs(priv,mt2266_init2,sizeof(mt2266_init2)); 240 - 241 - mt2266_writereg(priv,0x33,0x5e); 242 - mt2266_writereg(priv,0x10,0x10); 243 - mt2266_writereg(priv,0x10,0x00); 244 - 245 - mt2266_writeregs(priv,mt2266_init_8mhz,sizeof(mt2266_init_8mhz)); 246 - 195 + mt2266_writereg(priv, 0x11, 0x03); 196 + mt2266_writereg(priv, 0x11, 0x01); 197 + mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1)); 198 + mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2)); 199 + mt2266_writereg(priv, 0x33, 0x5e); 200 + mt2266_writereg(priv, 0x10, 0x10); 201 + mt2266_writereg(priv, 0x10, 0x00); 202 + mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz)); 247 203 msleep(25); 248 - mt2266_writereg(priv,0x17,0x6d); 249 - mt2266_writereg(priv,0x1c,0x00); 204 + mt2266_writereg(priv, 0x17, 0x6d); 205 + mt2266_writereg(priv, 0x1c, 0x00); 250 206 msleep(75); 251 - mt2266_writereg(priv,0x17,0x6d); 252 - mt2266_writereg(priv,0x1c,0xff); 207 + mt2266_writereg(priv, 0x17, 0x6d); 208 + mt2266_writereg(priv, 0x1c, 0xff); 253 209 } 254 210 255 211 static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency) ··· 275 217 276 218 static int mt2266_init(struct dvb_frontend *fe) 277 219 { 220 + int ret; 278 221 struct mt2266_priv *priv = fe->tuner_priv; 279 - mt2266_writereg(priv,0x17,0x6d); 280 - mt2266_writereg(priv,0x1c,0xff); 222 + ret = mt2266_writereg(priv, 0x17, 0x6d); 223 + if (ret < 0) 224 + return ret; 225 + ret = mt2266_writereg(priv, 0x1c, 0xff); 226 + if (ret < 0) 227 + return ret; 281 228 return 0; 282 229 } 283 230 284 231 static int mt2266_sleep(struct dvb_frontend *fe) 285 232 { 286 233 struct mt2266_priv *priv = fe->tuner_priv; 287 - mt2266_writereg(priv,0x17,0x6d); 288 - mt2266_writereg(priv,0x1c,0x00); 234 + mt2266_writereg(priv, 0x17, 0x6d); 235 + mt2266_writereg(priv, 0x1c, 0x00); 289 236 return 0; 290 237 } 291 238 ··· 304 241 static const struct dvb_tuner_ops mt2266_tuner_ops = { 305 242 .info = { 306 243 .name = "Microtune MT2266", 307 - .frequency_min = 470000000, 308 - .frequency_max = 860000000, 244 + .frequency_min = 174000000, 245 + .frequency_max = 862000000, 309 246 .frequency_step = 50000, 310 247 }, 311 248 .release = mt2266_release, ··· 327 264 328 265 priv->cfg = cfg; 329 266 priv->i2c = i2c; 267 + priv->band = MT2266_UHF; 330 268 331 - if (mt2266_readreg(priv,0,&id) != 0) { 269 + if (mt2266_readreg(priv, 0, &id)) { 332 270 kfree(priv); 333 271 return NULL; 334 272 }