1/* 2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview 3 * I2C address is allways 0xC0. 4 * 5 * 6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org) 7 * This code is placed under the terms of the GNU General Public License 8 * 9 * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa 10 * from their contributions on DScaler. 11 */ 12 13#include <linux/i2c.h> 14#include <linux/slab.h> 15#include <linux/delay.h> 16#include <linux/videodev2.h> 17#include "tuner-i2c.h" 18#include "tea5767.h" 19 20static int debug; 21module_param(debug, int, 0644); 22MODULE_PARM_DESC(debug, "enable verbose debug messages"); 23 24/*****************************************************************************/ 25 26struct tea5767_priv { 27 struct tuner_i2c_props i2c_props; 28 u32 frequency; 29 struct tea5767_ctrl ctrl; 30}; 31 32/*****************************************************************************/ 33 34/****************************** 35 * Write mode register values * 36 ******************************/ 37 38/* First register */ 39#define TEA5767_MUTE 0x80 /* Mutes output */ 40#define TEA5767_SEARCH 0x40 /* Activates station search */ 41/* Bits 0-5 for divider MSB */ 42 43/* Second register */ 44/* Bits 0-7 for divider LSB */ 45 46/* Third register */ 47 48/* Station search from botton to up */ 49#define TEA5767_SEARCH_UP 0x80 50 51/* Searches with ADC output = 10 */ 52#define TEA5767_SRCH_HIGH_LVL 0x60 53 54/* Searches with ADC output = 10 */ 55#define TEA5767_SRCH_MID_LVL 0x40 56 57/* Searches with ADC output = 5 */ 58#define TEA5767_SRCH_LOW_LVL 0x20 59 60/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ 61#define TEA5767_HIGH_LO_INJECT 0x10 62 63/* Disable stereo */ 64#define TEA5767_MONO 0x08 65 66/* Disable right channel and turns to mono */ 67#define TEA5767_MUTE_RIGHT 0x04 68 69/* Disable left channel and turns to mono */ 70#define TEA5767_MUTE_LEFT 0x02 71 72#define TEA5767_PORT1_HIGH 0x01 73 74/* Fourth register */ 75#define TEA5767_PORT2_HIGH 0x80 76/* Chips stops working. Only I2C bus remains on */ 77#define TEA5767_STDBY 0x40 78 79/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ 80#define TEA5767_JAPAN_BAND 0x20 81 82/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ 83#define TEA5767_XTAL_32768 0x10 84 85/* Cuts weak signals */ 86#define TEA5767_SOFT_MUTE 0x08 87 88/* Activates high cut control */ 89#define TEA5767_HIGH_CUT_CTRL 0x04 90 91/* Activates stereo noise control */ 92#define TEA5767_ST_NOISE_CTL 0x02 93 94/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ 95#define TEA5767_SRCH_IND 0x01 96 97/* Fifth register */ 98 99/* By activating, it will use Xtal at 13 MHz as reference for divider */ 100#define TEA5767_PLLREF_ENABLE 0x80 101 102/* By activating, deemphasis=50, or else, deemphasis of 50us */ 103#define TEA5767_DEEMPH_75 0X40 104 105/***************************** 106 * Read mode register values * 107 *****************************/ 108 109/* First register */ 110#define TEA5767_READY_FLAG_MASK 0x80 111#define TEA5767_BAND_LIMIT_MASK 0X40 112/* Bits 0-5 for divider MSB after search or preset */ 113 114/* Second register */ 115/* Bits 0-7 for divider LSB after search or preset */ 116 117/* Third register */ 118#define TEA5767_STEREO_MASK 0x80 119#define TEA5767_IF_CNTR_MASK 0x7f 120 121/* Fourth register */ 122#define TEA5767_ADC_LEVEL_MASK 0xf0 123 124/* should be 0 */ 125#define TEA5767_CHIP_ID_MASK 0x0f 126 127/* Fifth register */ 128/* Reserved for future extensions */ 129#define TEA5767_RESERVED_MASK 0xff 130 131/*****************************************************************************/ 132 133static void tea5767_status_dump(struct tea5767_priv *priv, 134 unsigned char *buffer) 135{ 136 unsigned int div, frq; 137 138 if (TEA5767_READY_FLAG_MASK & buffer[0]) 139 tuner_info("Ready Flag ON\n"); 140 else 141 tuner_info("Ready Flag OFF\n"); 142 143 if (TEA5767_BAND_LIMIT_MASK & buffer[0]) 144 tuner_info("Tuner at band limit\n"); 145 else 146 tuner_info("Tuner not at band limit\n"); 147 148 div = ((buffer[0] & 0x3f) << 8) | buffer[1]; 149 150 switch (priv->ctrl.xtal_freq) { 151 case TEA5767_HIGH_LO_13MHz: 152 frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */ 153 break; 154 case TEA5767_LOW_LO_13MHz: 155 frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */ 156 break; 157 case TEA5767_LOW_LO_32768: 158 frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */ 159 break; 160 case TEA5767_HIGH_LO_32768: 161 default: 162 frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */ 163 break; 164 } 165 buffer[0] = (div >> 8) & 0x3f; 166 buffer[1] = div & 0xff; 167 168 tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n", 169 frq / 1000, frq % 1000, div); 170 171 if (TEA5767_STEREO_MASK & buffer[2]) 172 tuner_info("Stereo\n"); 173 else 174 tuner_info("Mono\n"); 175 176 tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); 177 178 tuner_info("ADC Level = %d\n", 179 (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); 180 181 tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); 182 183 tuner_info("Reserved = 0x%02x\n", 184 (buffer[4] & TEA5767_RESERVED_MASK)); 185} 186 187/* Freq should be specifyed at 62.5 Hz */ 188static int set_radio_freq(struct dvb_frontend *fe, 189 struct analog_parameters *params) 190{ 191 struct tea5767_priv *priv = fe->tuner_priv; 192 unsigned int frq = params->frequency; 193 unsigned char buffer[5]; 194 unsigned div; 195 int rc; 196 197 tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000); 198 199 buffer[2] = 0; 200 201 if (priv->ctrl.port1) 202 buffer[2] |= TEA5767_PORT1_HIGH; 203 204 if (params->audmode == V4L2_TUNER_MODE_MONO) { 205 tuner_dbg("TEA5767 set to mono\n"); 206 buffer[2] |= TEA5767_MONO; 207 } else { 208 tuner_dbg("TEA5767 set to stereo\n"); 209 } 210 211 212 buffer[3] = 0; 213 214 if (priv->ctrl.port2) 215 buffer[3] |= TEA5767_PORT2_HIGH; 216 217 if (priv->ctrl.high_cut) 218 buffer[3] |= TEA5767_HIGH_CUT_CTRL; 219 220 if (priv->ctrl.st_noise) 221 buffer[3] |= TEA5767_ST_NOISE_CTL; 222 223 if (priv->ctrl.soft_mute) 224 buffer[3] |= TEA5767_SOFT_MUTE; 225 226 if (priv->ctrl.japan_band) 227 buffer[3] |= TEA5767_JAPAN_BAND; 228 229 buffer[4] = 0; 230 231 if (priv->ctrl.deemph_75) 232 buffer[4] |= TEA5767_DEEMPH_75; 233 234 if (priv->ctrl.pllref) 235 buffer[4] |= TEA5767_PLLREF_ENABLE; 236 237 238 /* Rounds freq to next decimal value - for 62.5 KHz step */ 239 /* frq = 20*(frq/16)+radio_frq[frq%16]; */ 240 241 switch (priv->ctrl.xtal_freq) { 242 case TEA5767_HIGH_LO_13MHz: 243 tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n"); 244 buffer[2] |= TEA5767_HIGH_LO_INJECT; 245 div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000; 246 break; 247 case TEA5767_LOW_LO_13MHz: 248 tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n"); 249 250 div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000; 251 break; 252 case TEA5767_LOW_LO_32768: 253 tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n"); 254 buffer[3] |= TEA5767_XTAL_32768; 255 /* const 700=4000*175 Khz - to adjust freq to right value */ 256 div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15; 257 break; 258 case TEA5767_HIGH_LO_32768: 259 default: 260 tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n"); 261 262 buffer[2] |= TEA5767_HIGH_LO_INJECT; 263 buffer[3] |= TEA5767_XTAL_32768; 264 div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15; 265 break; 266 } 267 buffer[0] = (div >> 8) & 0x3f; 268 buffer[1] = div & 0xff; 269 270 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5))) 271 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 272 273 if (debug) { 274 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) 275 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 276 else 277 tea5767_status_dump(priv, buffer); 278 } 279 280 priv->frequency = frq * 125 / 2; 281 282 return 0; 283} 284 285static int tea5767_read_status(struct dvb_frontend *fe, char *buffer) 286{ 287 struct tea5767_priv *priv = fe->tuner_priv; 288 int rc; 289 290 memset(buffer, 0, 5); 291 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) { 292 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 293 return -EREMOTEIO; 294 } 295 296 return 0; 297} 298 299static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer) 300{ 301 struct tea5767_priv *priv = fe->tuner_priv; 302 303 int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8); 304 305 tuner_dbg("Signal strength: %d\n", signal); 306 307 return signal; 308} 309 310static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer) 311{ 312 struct tea5767_priv *priv = fe->tuner_priv; 313 314 int stereo = buffer[2] & TEA5767_STEREO_MASK; 315 316 tuner_dbg("Radio ST GET = %02x\n", stereo); 317 318 return (stereo ? V4L2_TUNER_SUB_STEREO : 0); 319} 320 321static int tea5767_get_status(struct dvb_frontend *fe, u32 *status) 322{ 323 unsigned char buffer[5]; 324 325 *status = 0; 326 327 if (0 == tea5767_read_status(fe, buffer)) { 328 if (tea5767_signal(fe, buffer)) 329 *status = TUNER_STATUS_LOCKED; 330 if (tea5767_stereo(fe, buffer)) 331 *status |= TUNER_STATUS_STEREO; 332 } 333 334 return 0; 335} 336 337static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength) 338{ 339 unsigned char buffer[5]; 340 341 *strength = 0; 342 343 if (0 == tea5767_read_status(fe, buffer)) 344 *strength = tea5767_signal(fe, buffer); 345 346 return 0; 347} 348 349static int tea5767_standby(struct dvb_frontend *fe) 350{ 351 unsigned char buffer[5]; 352 struct tea5767_priv *priv = fe->tuner_priv; 353 unsigned div, rc; 354 355 div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */ 356 buffer[0] = (div >> 8) & 0x3f; 357 buffer[1] = div & 0xff; 358 buffer[2] = TEA5767_PORT1_HIGH; 359 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | 360 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY; 361 buffer[4] = 0; 362 363 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5))) 364 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 365 366 return 0; 367} 368 369int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr) 370{ 371 struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr }; 372 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 373 int rc; 374 375 if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) { 376 printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc); 377 return -EINVAL; 378 } 379 380 /* If all bytes are the same then it's a TV tuner and not a tea5767 */ 381 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && 382 buffer[0] == buffer[3] && buffer[0] == buffer[4]) { 383 printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n"); 384 return -EINVAL; 385 } 386 387 /* Status bytes: 388 * Byte 4: bit 3:1 : CI (Chip Identification) == 0 389 * bit 0 : internally set to 0 390 * Byte 5: bit 7:0 : == 0 391 */ 392 if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) { 393 printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n"); 394 return -EINVAL; 395 } 396 397 398 return 0; 399} 400 401static int tea5767_release(struct dvb_frontend *fe) 402{ 403 kfree(fe->tuner_priv); 404 fe->tuner_priv = NULL; 405 406 return 0; 407} 408 409static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency) 410{ 411 struct tea5767_priv *priv = fe->tuner_priv; 412 *frequency = priv->frequency; 413 414 return 0; 415} 416 417static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg) 418{ 419 struct tea5767_priv *priv = fe->tuner_priv; 420 421 memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl)); 422 423 return 0; 424} 425 426static struct dvb_tuner_ops tea5767_tuner_ops = { 427 .info = { 428 .name = "tea5767", // Philips TEA5767HN FM Radio 429 }, 430 431 .set_analog_params = set_radio_freq, 432 .set_config = tea5767_set_config, 433 .sleep = tea5767_standby, 434 .release = tea5767_release, 435 .get_frequency = tea5767_get_frequency, 436 .get_status = tea5767_get_status, 437 .get_rf_strength = tea5767_get_rf_strength, 438}; 439 440struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, 441 struct i2c_adapter* i2c_adap, 442 u8 i2c_addr) 443{ 444 struct tea5767_priv *priv = NULL; 445 446 priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL); 447 if (priv == NULL) 448 return NULL; 449 fe->tuner_priv = priv; 450 451 priv->i2c_props.addr = i2c_addr; 452 priv->i2c_props.adap = i2c_adap; 453 priv->i2c_props.name = "tea5767"; 454 455 priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768; 456 priv->ctrl.port1 = 1; 457 priv->ctrl.port2 = 1; 458 priv->ctrl.high_cut = 1; 459 priv->ctrl.st_noise = 1; 460 priv->ctrl.japan_band = 1; 461 462 memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops, 463 sizeof(struct dvb_tuner_ops)); 464 465 tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio"); 466 467 return fe; 468} 469 470EXPORT_SYMBOL_GPL(tea5767_attach); 471EXPORT_SYMBOL_GPL(tea5767_autodetection); 472 473MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver"); 474MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 475MODULE_LICENSE("GPL"); 476