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/videodev.h> 15#include <linux/delay.h> 16#include <media/tuner.h> 17 18#define PREFIX "TEA5767 " 19 20/* from tuner-core.c */ 21extern int tuner_debug; 22 23/*****************************************************************************/ 24 25/****************************** 26 * Write mode register values * 27 ******************************/ 28 29/* First register */ 30#define TEA5767_MUTE 0x80 /* Mutes output */ 31#define TEA5767_SEARCH 0x40 /* Activates station search */ 32/* Bits 0-5 for divider MSB */ 33 34/* Second register */ 35/* Bits 0-7 for divider LSB */ 36 37/* Third register */ 38 39/* Station search from botton to up */ 40#define TEA5767_SEARCH_UP 0x80 41 42/* Searches with ADC output = 10 */ 43#define TEA5767_SRCH_HIGH_LVL 0x60 44 45/* Searches with ADC output = 10 */ 46#define TEA5767_SRCH_MID_LVL 0x40 47 48/* Searches with ADC output = 5 */ 49#define TEA5767_SRCH_LOW_LVL 0x20 50 51/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ 52#define TEA5767_HIGH_LO_INJECT 0x10 53 54/* Disable stereo */ 55#define TEA5767_MONO 0x08 56 57/* Disable right channel and turns to mono */ 58#define TEA5767_MUTE_RIGHT 0x04 59 60/* Disable left channel and turns to mono */ 61#define TEA5767_MUTE_LEFT 0x02 62 63#define TEA5767_PORT1_HIGH 0x01 64 65/* Fourth register */ 66#define TEA5767_PORT2_HIGH 0x80 67/* Chips stops working. Only I2C bus remains on */ 68#define TEA5767_STDBY 0x40 69 70/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ 71#define TEA5767_JAPAN_BAND 0x20 72 73/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ 74#define TEA5767_XTAL_32768 0x10 75 76/* Cuts weak signals */ 77#define TEA5767_SOFT_MUTE 0x08 78 79/* Activates high cut control */ 80#define TEA5767_HIGH_CUT_CTRL 0x04 81 82/* Activates stereo noise control */ 83#define TEA5767_ST_NOISE_CTL 0x02 84 85/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ 86#define TEA5767_SRCH_IND 0x01 87 88/* Fifth register */ 89 90/* By activating, it will use Xtal at 13 MHz as reference for divider */ 91#define TEA5767_PLLREF_ENABLE 0x80 92 93/* By activating, deemphasis=50, or else, deemphasis of 50us */ 94#define TEA5767_DEEMPH_75 0X40 95 96/***************************** 97 * Read mode register values * 98 *****************************/ 99 100/* First register */ 101#define TEA5767_READY_FLAG_MASK 0x80 102#define TEA5767_BAND_LIMIT_MASK 0X40 103/* Bits 0-5 for divider MSB after search or preset */ 104 105/* Second register */ 106/* Bits 0-7 for divider LSB after search or preset */ 107 108/* Third register */ 109#define TEA5767_STEREO_MASK 0x80 110#define TEA5767_IF_CNTR_MASK 0x7f 111 112/* Fourth register */ 113#define TEA5767_ADC_LEVEL_MASK 0xf0 114 115/* should be 0 */ 116#define TEA5767_CHIP_ID_MASK 0x0f 117 118/* Fifth register */ 119/* Reserved for future extensions */ 120#define TEA5767_RESERVED_MASK 0xff 121 122enum tea5767_xtal_freq { 123 TEA5767_LOW_LO_32768 = 0, 124 TEA5767_HIGH_LO_32768 = 1, 125 TEA5767_LOW_LO_13MHz = 2, 126 TEA5767_HIGH_LO_13MHz = 3, 127}; 128 129 130/*****************************************************************************/ 131 132static void set_tv_freq(struct i2c_client *c, unsigned int freq) 133{ 134 struct tuner *t = i2c_get_clientdata(c); 135 136 tuner_warn("This tuner doesn't support TV freq.\n"); 137} 138 139static void tea5767_status_dump(unsigned char *buffer) 140{ 141 unsigned int div, frq; 142 143 if (TEA5767_READY_FLAG_MASK & buffer[0]) 144 printk(PREFIX "Ready Flag ON\n"); 145 else 146 printk(PREFIX "Ready Flag OFF\n"); 147 148 if (TEA5767_BAND_LIMIT_MASK & buffer[0]) 149 printk(PREFIX "Tuner at band limit\n"); 150 else 151 printk(PREFIX "Tuner not at band limit\n"); 152 153 div = ((buffer[0] & 0x3f) << 8) | buffer[1]; 154 155 switch (TEA5767_HIGH_LO_32768) { 156 case TEA5767_HIGH_LO_13MHz: 157 frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */ 158 break; 159 case TEA5767_LOW_LO_13MHz: 160 frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */ 161 break; 162 case TEA5767_LOW_LO_32768: 163 frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */ 164 break; 165 case TEA5767_HIGH_LO_32768: 166 default: 167 frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */ 168 break; 169 } 170 buffer[0] = (div >> 8) & 0x3f; 171 buffer[1] = div & 0xff; 172 173 printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", 174 frq / 1000, frq % 1000, div); 175 176 if (TEA5767_STEREO_MASK & buffer[2]) 177 printk(PREFIX "Stereo\n"); 178 else 179 printk(PREFIX "Mono\n"); 180 181 printk(PREFIX "IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK); 182 183 printk(PREFIX "ADC Level = %d\n", 184 (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4); 185 186 printk(PREFIX "Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK)); 187 188 printk(PREFIX "Reserved = 0x%02x\n", 189 (buffer[4] & TEA5767_RESERVED_MASK)); 190} 191 192/* Freq should be specifyed at 62.5 Hz */ 193static void set_radio_freq(struct i2c_client *c, unsigned int frq) 194{ 195 struct tuner *t = i2c_get_clientdata(c); 196 unsigned char buffer[5]; 197 unsigned div; 198 int rc; 199 200 tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000); 201 202 /* Rounds freq to next decimal value - for 62.5 KHz step */ 203 /* frq = 20*(frq/16)+radio_frq[frq%16]; */ 204 205 buffer[2] = TEA5767_PORT1_HIGH; 206 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | 207 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; 208 buffer[4] = 0; 209 210 if (t->audmode == V4L2_TUNER_MODE_MONO) { 211 tuner_dbg("TEA5767 set to mono\n"); 212 buffer[2] |= TEA5767_MONO; 213 } else { 214 tuner_dbg("TEA5767 set to stereo\n"); 215 } 216 217 /* Should be replaced */ 218 switch (TEA5767_HIGH_LO_32768) { 219 case TEA5767_HIGH_LO_13MHz: 220 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); 221 buffer[2] |= TEA5767_HIGH_LO_INJECT; 222 buffer[4] |= TEA5767_PLLREF_ENABLE; 223 div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000; 224 break; 225 case TEA5767_LOW_LO_13MHz: 226 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); 227 228 buffer[4] |= TEA5767_PLLREF_ENABLE; 229 div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000; 230 break; 231 case TEA5767_LOW_LO_32768: 232 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); 233 buffer[3] |= TEA5767_XTAL_32768; 234 /* const 700=4000*175 Khz - to adjust freq to right value */ 235 div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15; 236 break; 237 case TEA5767_HIGH_LO_32768: 238 default: 239 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n"); 240 241 buffer[2] |= TEA5767_HIGH_LO_INJECT; 242 buffer[3] |= TEA5767_XTAL_32768; 243 div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15; 244 break; 245 } 246 buffer[0] = (div >> 8) & 0x3f; 247 buffer[1] = div & 0xff; 248 249 if (5 != (rc = i2c_master_send(c, buffer, 5))) 250 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 251 252 if (tuner_debug) { 253 if (5 != (rc = i2c_master_recv(c, buffer, 5))) 254 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 255 else 256 tea5767_status_dump(buffer); 257 } 258} 259 260static int tea5767_signal(struct i2c_client *c) 261{ 262 unsigned char buffer[5]; 263 int rc; 264 struct tuner *t = i2c_get_clientdata(c); 265 266 memset(buffer, 0, sizeof(buffer)); 267 if (5 != (rc = i2c_master_recv(c, buffer, 5))) 268 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 269 270 return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8); 271} 272 273static int tea5767_stereo(struct i2c_client *c) 274{ 275 unsigned char buffer[5]; 276 int rc; 277 struct tuner *t = i2c_get_clientdata(c); 278 279 memset(buffer, 0, sizeof(buffer)); 280 if (5 != (rc = i2c_master_recv(c, buffer, 5))) 281 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 282 283 rc = buffer[2] & TEA5767_STEREO_MASK; 284 285 tuner_dbg("TEA5767 radio ST GET = %02x\n", rc); 286 287 return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0); 288} 289 290static void tea5767_standby(struct i2c_client *c) 291{ 292 unsigned char buffer[5]; 293 struct tuner *t = i2c_get_clientdata(c); 294 unsigned div, rc; 295 296 div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */ 297 buffer[0] = (div >> 8) & 0x3f; 298 buffer[1] = div & 0xff; 299 buffer[2] = TEA5767_PORT1_HIGH; 300 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | 301 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY; 302 buffer[4] = 0; 303 304 if (5 != (rc = i2c_master_send(c, buffer, 5))) 305 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); 306} 307 308int tea5767_autodetection(struct i2c_client *c) 309{ 310 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 311 int rc; 312 struct tuner *t = i2c_get_clientdata(c); 313 314 if ((rc = i2c_master_recv(c, buffer, 7))< 5) { 315 tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc); 316 return EINVAL; 317 } 318 319 /* If all bytes are the same then it's a TV tuner and not a tea5767 */ 320 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && 321 buffer[0] == buffer[3] && buffer[0] == buffer[4]) { 322 tuner_warn("All bytes are equal. It is not a TEA5767\n"); 323 return EINVAL; 324 } 325 326 /* Status bytes: 327 * Byte 4: bit 3:1 : CI (Chip Identification) == 0 328 * bit 0 : internally set to 0 329 * Byte 5: bit 7:0 : == 0 330 */ 331 if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) { 332 tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); 333 return EINVAL; 334 } 335 336 /* It seems that tea5767 returns 0xff after the 5th byte */ 337 if ((buffer[5] != 0xff) || (buffer[6] != 0xff)) { 338 tuner_warn("Returned more than 5 bytes. It is not a TEA5767\n"); 339 return EINVAL; 340 } 341 342 tuner_warn("TEA5767 detected.\n"); 343 return 0; 344} 345 346int tea5767_tuner_init(struct i2c_client *c) 347{ 348 struct tuner *t = i2c_get_clientdata(c); 349 350 tuner_info("type set to %d (%s)\n", t->type, "Philips TEA5767HN FM Radio"); 351 strlcpy(c->name, "tea5767", sizeof(c->name)); 352 353 t->set_tv_freq = set_tv_freq; 354 t->set_radio_freq = set_radio_freq; 355 t->has_signal = tea5767_signal; 356 t->is_stereo = tea5767_stereo; 357 t->standby = tea5767_standby; 358 359 return (0); 360} 361