1/* 2 * ISDB-T driver for VA1J5JF8007/VA1J5JF8011 3 * 4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info> 5 * 6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/ 7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 */ 23 24#include <linux/kernel.h> 25#include <linux/module.h> 26#include <linux/slab.h> 27#include <linux/i2c.h> 28#include "dvb_frontend.h" 29#include "dvb_math.h" 30#include "va1j5jf8007t.h" 31 32enum va1j5jf8007t_tune_state { 33 VA1J5JF8007T_IDLE, 34 VA1J5JF8007T_SET_FREQUENCY, 35 VA1J5JF8007T_CHECK_FREQUENCY, 36 VA1J5JF8007T_SET_MODULATION, 37 VA1J5JF8007T_CHECK_MODULATION, 38 VA1J5JF8007T_TRACK, 39 VA1J5JF8007T_ABORT, 40}; 41 42struct va1j5jf8007t_state { 43 const struct va1j5jf8007t_config *config; 44 struct i2c_adapter *adap; 45 struct dvb_frontend fe; 46 enum va1j5jf8007t_tune_state tune_state; 47}; 48 49static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr) 50{ 51 struct va1j5jf8007t_state *state; 52 u8 addr; 53 int i; 54 u8 write_buf[1], read_buf[1]; 55 struct i2c_msg msgs[2]; 56 s32 word, x, y; 57 58 state = fe->demodulator_priv; 59 addr = state->config->demod_address; 60 61 word = 0; 62 for (i = 0; i < 3; i++) { 63 write_buf[0] = 0x8b + i; 64 65 msgs[0].addr = addr; 66 msgs[0].flags = 0; 67 msgs[0].len = sizeof(write_buf); 68 msgs[0].buf = write_buf; 69 70 msgs[1].addr = addr; 71 msgs[1].flags = I2C_M_RD; 72 msgs[1].len = sizeof(read_buf); 73 msgs[1].buf = read_buf; 74 75 if (i2c_transfer(state->adap, msgs, 2) != 2) 76 return -EREMOTEIO; 77 78 word <<= 8; 79 word |= read_buf[0]; 80 } 81 82 if (!word) 83 return -EIO; 84 85 x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24)); 86 y = (24ll << 46) / 1000000; 87 y = ((s64)y * x >> 30) - (16ll << 40) / 10000; 88 y = ((s64)y * x >> 29) + (398ll << 35) / 10000; 89 y = ((s64)y * x >> 30) + (5491ll << 29) / 10000; 90 y = ((s64)y * x >> 30) + (30965ll << 23) / 10000; 91 *snr = y >> 15; 92 return 0; 93} 94 95static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe) 96{ 97 return DVBFE_ALGO_HW; 98} 99 100static int 101va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status) 102{ 103 struct va1j5jf8007t_state *state; 104 105 state = fe->demodulator_priv; 106 107 switch (state->tune_state) { 108 case VA1J5JF8007T_IDLE: 109 case VA1J5JF8007T_SET_FREQUENCY: 110 case VA1J5JF8007T_CHECK_FREQUENCY: 111 *status = 0; 112 return 0; 113 114 115 case VA1J5JF8007T_SET_MODULATION: 116 case VA1J5JF8007T_CHECK_MODULATION: 117 case VA1J5JF8007T_ABORT: 118 *status |= FE_HAS_SIGNAL; 119 return 0; 120 121 case VA1J5JF8007T_TRACK: 122 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; 123 return 0; 124 } 125 126 BUG(); 127} 128 129struct va1j5jf8007t_cb_map { 130 u32 frequency; 131 u8 cb; 132}; 133 134static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = { 135 { 90000000, 0x80 }, 136 { 140000000, 0x81 }, 137 { 170000000, 0xa1 }, 138 { 220000000, 0x62 }, 139 { 330000000, 0xa2 }, 140 { 402000000, 0xe2 }, 141 { 450000000, 0x64 }, 142 { 550000000, 0x84 }, 143 { 600000000, 0xa4 }, 144 { 700000000, 0xc4 }, 145}; 146 147static u8 va1j5jf8007t_lookup_cb(u32 frequency) 148{ 149 int i; 150 const struct va1j5jf8007t_cb_map *map; 151 152 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) { 153 map = &va1j5jf8007t_cb_maps[i]; 154 if (frequency < map->frequency) 155 return map->cb; 156 } 157 return 0xe4; 158} 159 160static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state) 161{ 162 u32 frequency; 163 u16 word; 164 u8 buf[6]; 165 struct i2c_msg msg; 166 167 frequency = state->fe.dtv_property_cache.frequency; 168 169 word = (frequency + 71428) / 142857 + 399; 170 buf[0] = 0xfe; 171 buf[1] = 0xc2; 172 buf[2] = word >> 8; 173 buf[3] = word; 174 buf[4] = 0x80; 175 buf[5] = va1j5jf8007t_lookup_cb(frequency); 176 177 msg.addr = state->config->demod_address; 178 msg.flags = 0; 179 msg.len = sizeof(buf); 180 msg.buf = buf; 181 182 if (i2c_transfer(state->adap, &msg, 1) != 1) 183 return -EREMOTEIO; 184 185 return 0; 186} 187 188static int 189va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock) 190{ 191 u8 addr; 192 u8 write_buf[2], read_buf[1]; 193 struct i2c_msg msgs[2]; 194 195 addr = state->config->demod_address; 196 197 write_buf[0] = 0xfe; 198 write_buf[1] = 0xc3; 199 200 msgs[0].addr = addr; 201 msgs[0].flags = 0; 202 msgs[0].len = sizeof(write_buf); 203 msgs[0].buf = write_buf; 204 205 msgs[1].addr = addr; 206 msgs[1].flags = I2C_M_RD; 207 msgs[1].len = sizeof(read_buf); 208 msgs[1].buf = read_buf; 209 210 if (i2c_transfer(state->adap, msgs, 2) != 2) 211 return -EREMOTEIO; 212 213 *lock = read_buf[0] & 0x40; 214 return 0; 215} 216 217static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state) 218{ 219 u8 buf[2]; 220 struct i2c_msg msg; 221 222 buf[0] = 0x01; 223 buf[1] = 0x40; 224 225 msg.addr = state->config->demod_address; 226 msg.flags = 0; 227 msg.len = sizeof(buf); 228 msg.buf = buf; 229 230 if (i2c_transfer(state->adap, &msg, 1) != 1) 231 return -EREMOTEIO; 232 233 return 0; 234} 235 236static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state, 237 int *lock, int *retry) 238{ 239 u8 addr; 240 u8 write_buf[1], read_buf[1]; 241 struct i2c_msg msgs[2]; 242 243 addr = state->config->demod_address; 244 245 write_buf[0] = 0x80; 246 247 msgs[0].addr = addr; 248 msgs[0].flags = 0; 249 msgs[0].len = sizeof(write_buf); 250 msgs[0].buf = write_buf; 251 252 msgs[1].addr = addr; 253 msgs[1].flags = I2C_M_RD; 254 msgs[1].len = sizeof(read_buf); 255 msgs[1].buf = read_buf; 256 257 if (i2c_transfer(state->adap, msgs, 2) != 2) 258 return -EREMOTEIO; 259 260 *lock = !(read_buf[0] & 0x10); 261 *retry = read_buf[0] & 0x80; 262 return 0; 263} 264 265static int 266va1j5jf8007t_tune(struct dvb_frontend *fe, 267 bool re_tune, 268 unsigned int mode_flags, unsigned int *delay, 269 fe_status_t *status) 270{ 271 struct va1j5jf8007t_state *state; 272 int ret; 273 int lock = 0, retry = 0; 274 275 state = fe->demodulator_priv; 276 277 if (re_tune) 278 state->tune_state = VA1J5JF8007T_SET_FREQUENCY; 279 280 switch (state->tune_state) { 281 case VA1J5JF8007T_IDLE: 282 *delay = 3 * HZ; 283 *status = 0; 284 return 0; 285 286 case VA1J5JF8007T_SET_FREQUENCY: 287 ret = va1j5jf8007t_set_frequency(state); 288 if (ret < 0) 289 return ret; 290 291 state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY; 292 *delay = 0; 293 *status = 0; 294 return 0; 295 296 case VA1J5JF8007T_CHECK_FREQUENCY: 297 ret = va1j5jf8007t_check_frequency(state, &lock); 298 if (ret < 0) 299 return ret; 300 301 if (!lock) { 302 *delay = (HZ + 999) / 1000; 303 *status = 0; 304 return 0; 305 } 306 307 state->tune_state = VA1J5JF8007T_SET_MODULATION; 308 *delay = 0; 309 *status = FE_HAS_SIGNAL; 310 return 0; 311 312 case VA1J5JF8007T_SET_MODULATION: 313 ret = va1j5jf8007t_set_modulation(state); 314 if (ret < 0) 315 return ret; 316 317 state->tune_state = VA1J5JF8007T_CHECK_MODULATION; 318 *delay = 0; 319 *status = FE_HAS_SIGNAL; 320 return 0; 321 322 case VA1J5JF8007T_CHECK_MODULATION: 323 ret = va1j5jf8007t_check_modulation(state, &lock, &retry); 324 if (ret < 0) 325 return ret; 326 327 if (!lock) { 328 if (!retry) { 329 state->tune_state = VA1J5JF8007T_ABORT; 330 *delay = 3 * HZ; 331 *status = FE_HAS_SIGNAL; 332 return 0; 333 } 334 *delay = (HZ + 999) / 1000; 335 *status = FE_HAS_SIGNAL; 336 return 0; 337 } 338 339 state->tune_state = VA1J5JF8007T_TRACK; 340 /* fall through */ 341 342 case VA1J5JF8007T_TRACK: 343 *delay = 3 * HZ; 344 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK; 345 return 0; 346 347 case VA1J5JF8007T_ABORT: 348 *delay = 3 * HZ; 349 *status = FE_HAS_SIGNAL; 350 return 0; 351 } 352 353 BUG(); 354} 355 356static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state) 357{ 358 u8 buf[7]; 359 struct i2c_msg msg; 360 361 buf[0] = 0xfe; 362 buf[1] = 0xc2; 363 buf[2] = 0x01; 364 buf[3] = 0x8f; 365 buf[4] = 0xc1; 366 buf[5] = 0x80; 367 buf[6] = 0x80; 368 369 msg.addr = state->config->demod_address; 370 msg.flags = 0; 371 msg.len = sizeof(buf); 372 msg.buf = buf; 373 374 if (i2c_transfer(state->adap, &msg, 1) != 1) 375 return -EREMOTEIO; 376 377 return 0; 378} 379 380static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep) 381{ 382 u8 buf[2]; 383 struct i2c_msg msg; 384 385 buf[0] = 0x03; 386 buf[1] = sleep ? 0x90 : 0x80; 387 388 msg.addr = state->config->demod_address; 389 msg.flags = 0; 390 msg.len = sizeof(buf); 391 msg.buf = buf; 392 393 if (i2c_transfer(state->adap, &msg, 1) != 1) 394 return -EREMOTEIO; 395 396 return 0; 397} 398 399static int va1j5jf8007t_sleep(struct dvb_frontend *fe) 400{ 401 struct va1j5jf8007t_state *state; 402 int ret; 403 404 state = fe->demodulator_priv; 405 406 ret = va1j5jf8007t_init_frequency(state); 407 if (ret < 0) 408 return ret; 409 410 return va1j5jf8007t_set_sleep(state, 1); 411} 412 413static int va1j5jf8007t_init(struct dvb_frontend *fe) 414{ 415 struct va1j5jf8007t_state *state; 416 417 state = fe->demodulator_priv; 418 state->tune_state = VA1J5JF8007T_IDLE; 419 420 return va1j5jf8007t_set_sleep(state, 0); 421} 422 423static void va1j5jf8007t_release(struct dvb_frontend *fe) 424{ 425 struct va1j5jf8007t_state *state; 426 state = fe->demodulator_priv; 427 kfree(state); 428} 429 430static struct dvb_frontend_ops va1j5jf8007t_ops = { 431 .delsys = { SYS_ISDBT }, 432 .info = { 433 .name = "VA1J5JF8007/VA1J5JF8011 ISDB-T", 434 .frequency_min = 90000000, 435 .frequency_max = 770000000, 436 .frequency_stepsize = 142857, 437 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | 438 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | 439 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO, 440 }, 441 442 .read_snr = va1j5jf8007t_read_snr, 443 .get_frontend_algo = va1j5jf8007t_get_frontend_algo, 444 .read_status = va1j5jf8007t_read_status, 445 .tune = va1j5jf8007t_tune, 446 .sleep = va1j5jf8007t_sleep, 447 .init = va1j5jf8007t_init, 448 .release = va1j5jf8007t_release, 449}; 450 451static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = { 452 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, 453 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00}, 454 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03}, 455 {0xef, 0x01} 456}; 457 458static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = { 459 {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83}, 460 {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c}, 461 {0x77, 0x03}, {0xef, 0x01} 462}; 463 464int va1j5jf8007t_prepare(struct dvb_frontend *fe) 465{ 466 struct va1j5jf8007t_state *state; 467 const u8 (*bufs)[2]; 468 int size; 469 u8 buf[2]; 470 struct i2c_msg msg; 471 int i; 472 473 state = fe->demodulator_priv; 474 475 switch (state->config->frequency) { 476 case VA1J5JF8007T_20MHZ: 477 bufs = va1j5jf8007t_20mhz_prepare_bufs; 478 size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs); 479 break; 480 case VA1J5JF8007T_25MHZ: 481 bufs = va1j5jf8007t_25mhz_prepare_bufs; 482 size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs); 483 break; 484 default: 485 return -EINVAL; 486 } 487 488 msg.addr = state->config->demod_address; 489 msg.flags = 0; 490 msg.len = sizeof(buf); 491 msg.buf = buf; 492 493 for (i = 0; i < size; i++) { 494 memcpy(buf, bufs[i], sizeof(buf)); 495 if (i2c_transfer(state->adap, &msg, 1) != 1) 496 return -EREMOTEIO; 497 } 498 499 return va1j5jf8007t_init_frequency(state); 500} 501 502struct dvb_frontend * 503va1j5jf8007t_attach(const struct va1j5jf8007t_config *config, 504 struct i2c_adapter *adap) 505{ 506 struct va1j5jf8007t_state *state; 507 struct dvb_frontend *fe; 508 u8 buf[2]; 509 struct i2c_msg msg; 510 511 state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL); 512 if (!state) 513 return NULL; 514 515 state->config = config; 516 state->adap = adap; 517 518 fe = &state->fe; 519 memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops)); 520 fe->demodulator_priv = state; 521 522 buf[0] = 0x01; 523 buf[1] = 0x80; 524 525 msg.addr = state->config->demod_address; 526 msg.flags = 0; 527 msg.len = sizeof(buf); 528 msg.buf = buf; 529 530 if (i2c_transfer(state->adap, &msg, 1) != 1) { 531 kfree(state); 532 return NULL; 533 } 534 535 return fe; 536} 537