1/* 2 * Sony CXD2820R demodulator driver 3 * 4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi> 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 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 22#include "cxd2820r_priv.h" 23 24int cxd2820r_set_frontend_t(struct dvb_frontend *fe) 25{ 26 struct cxd2820r_priv *priv = fe->demodulator_priv; 27 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 28 int ret, i, bw_i; 29 u32 if_freq, if_ctl; 30 u64 num; 31 u8 buf[3], bw_param; 32 u8 bw_params1[][5] = { 33 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */ 34 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */ 35 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */ 36 }; 37 u8 bw_params2[][2] = { 38 { 0x1f, 0xdc }, /* 6 MHz */ 39 { 0x12, 0xf8 }, /* 7 MHz */ 40 { 0x01, 0xe0 }, /* 8 MHz */ 41 }; 42 struct reg_val_mask tab[] = { 43 { 0x00080, 0x00, 0xff }, 44 { 0x00081, 0x03, 0xff }, 45 { 0x00085, 0x07, 0xff }, 46 { 0x00088, 0x01, 0xff }, 47 48 { 0x00070, priv->cfg.ts_mode, 0xff }, 49 { 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 }, 50 { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 }, 51 { 0x000a5, 0x00, 0x01 }, 52 { 0x00082, 0x20, 0x60 }, 53 { 0x000c2, 0xc3, 0xff }, 54 { 0x0016a, 0x50, 0xff }, 55 { 0x00427, 0x41, 0xff }, 56 }; 57 58 dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__, 59 c->frequency, c->bandwidth_hz); 60 61 switch (c->bandwidth_hz) { 62 case 6000000: 63 bw_i = 0; 64 bw_param = 2; 65 break; 66 case 7000000: 67 bw_i = 1; 68 bw_param = 1; 69 break; 70 case 8000000: 71 bw_i = 2; 72 bw_param = 0; 73 break; 74 default: 75 return -EINVAL; 76 } 77 78 /* program tuner */ 79 if (fe->ops.tuner_ops.set_params) 80 fe->ops.tuner_ops.set_params(fe); 81 82 if (priv->delivery_system != SYS_DVBT) { 83 for (i = 0; i < ARRAY_SIZE(tab); i++) { 84 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, 85 tab[i].val, tab[i].mask); 86 if (ret) 87 goto error; 88 } 89 } 90 91 priv->delivery_system = SYS_DVBT; 92 priv->ber_running = false; /* tune stops BER counter */ 93 94 /* program IF frequency */ 95 if (fe->ops.tuner_ops.get_if_frequency) { 96 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); 97 if (ret) 98 goto error; 99 } else 100 if_freq = 0; 101 102 dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq); 103 104 num = if_freq / 1000; /* Hz => kHz */ 105 num *= 0x1000000; 106 if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000); 107 buf[0] = ((if_ctl >> 16) & 0xff); 108 buf[1] = ((if_ctl >> 8) & 0xff); 109 buf[2] = ((if_ctl >> 0) & 0xff); 110 111 ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3); 112 if (ret) 113 goto error; 114 115 ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5); 116 if (ret) 117 goto error; 118 119 ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0); 120 if (ret) 121 goto error; 122 123 ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2); 124 if (ret) 125 goto error; 126 127 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08); 128 if (ret) 129 goto error; 130 131 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01); 132 if (ret) 133 goto error; 134 135 return ret; 136error: 137 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 138 return ret; 139} 140 141int cxd2820r_get_frontend_t(struct dvb_frontend *fe) 142{ 143 struct cxd2820r_priv *priv = fe->demodulator_priv; 144 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 145 int ret; 146 u8 buf[2]; 147 148 ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf)); 149 if (ret) 150 goto error; 151 152 switch ((buf[0] >> 6) & 0x03) { 153 case 0: 154 c->modulation = QPSK; 155 break; 156 case 1: 157 c->modulation = QAM_16; 158 break; 159 case 2: 160 c->modulation = QAM_64; 161 break; 162 } 163 164 switch ((buf[1] >> 1) & 0x03) { 165 case 0: 166 c->transmission_mode = TRANSMISSION_MODE_2K; 167 break; 168 case 1: 169 c->transmission_mode = TRANSMISSION_MODE_8K; 170 break; 171 } 172 173 switch ((buf[1] >> 3) & 0x03) { 174 case 0: 175 c->guard_interval = GUARD_INTERVAL_1_32; 176 break; 177 case 1: 178 c->guard_interval = GUARD_INTERVAL_1_16; 179 break; 180 case 2: 181 c->guard_interval = GUARD_INTERVAL_1_8; 182 break; 183 case 3: 184 c->guard_interval = GUARD_INTERVAL_1_4; 185 break; 186 } 187 188 switch ((buf[0] >> 3) & 0x07) { 189 case 0: 190 c->hierarchy = HIERARCHY_NONE; 191 break; 192 case 1: 193 c->hierarchy = HIERARCHY_1; 194 break; 195 case 2: 196 c->hierarchy = HIERARCHY_2; 197 break; 198 case 3: 199 c->hierarchy = HIERARCHY_4; 200 break; 201 } 202 203 switch ((buf[0] >> 0) & 0x07) { 204 case 0: 205 c->code_rate_HP = FEC_1_2; 206 break; 207 case 1: 208 c->code_rate_HP = FEC_2_3; 209 break; 210 case 2: 211 c->code_rate_HP = FEC_3_4; 212 break; 213 case 3: 214 c->code_rate_HP = FEC_5_6; 215 break; 216 case 4: 217 c->code_rate_HP = FEC_7_8; 218 break; 219 } 220 221 switch ((buf[1] >> 5) & 0x07) { 222 case 0: 223 c->code_rate_LP = FEC_1_2; 224 break; 225 case 1: 226 c->code_rate_LP = FEC_2_3; 227 break; 228 case 2: 229 c->code_rate_LP = FEC_3_4; 230 break; 231 case 3: 232 c->code_rate_LP = FEC_5_6; 233 break; 234 case 4: 235 c->code_rate_LP = FEC_7_8; 236 break; 237 } 238 239 ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]); 240 if (ret) 241 goto error; 242 243 switch ((buf[0] >> 0) & 0x01) { 244 case 0: 245 c->inversion = INVERSION_OFF; 246 break; 247 case 1: 248 c->inversion = INVERSION_ON; 249 break; 250 } 251 252 return ret; 253error: 254 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 255 return ret; 256} 257 258int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber) 259{ 260 struct cxd2820r_priv *priv = fe->demodulator_priv; 261 int ret; 262 u8 buf[3], start_ber = 0; 263 *ber = 0; 264 265 if (priv->ber_running) { 266 ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf)); 267 if (ret) 268 goto error; 269 270 if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) { 271 *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0]; 272 start_ber = 1; 273 } 274 } else { 275 priv->ber_running = true; 276 start_ber = 1; 277 } 278 279 if (start_ber) { 280 /* (re)start BER */ 281 ret = cxd2820r_wr_reg(priv, 0x00079, 0x01); 282 if (ret) 283 goto error; 284 } 285 286 return ret; 287error: 288 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 289 return ret; 290} 291 292int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, 293 u16 *strength) 294{ 295 struct cxd2820r_priv *priv = fe->demodulator_priv; 296 int ret; 297 u8 buf[2]; 298 u16 tmp; 299 300 ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf)); 301 if (ret) 302 goto error; 303 304 tmp = (buf[0] & 0x0f) << 8 | buf[1]; 305 tmp = ~tmp & 0x0fff; 306 307 /* scale value to 0x0000-0xffff from 0x0000-0x0fff */ 308 *strength = tmp * 0xffff / 0x0fff; 309 310 return ret; 311error: 312 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 313 return ret; 314} 315 316int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr) 317{ 318 struct cxd2820r_priv *priv = fe->demodulator_priv; 319 int ret; 320 u8 buf[2]; 321 u16 tmp; 322 /* report SNR in dB * 10 */ 323 324 ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf)); 325 if (ret) 326 goto error; 327 328 tmp = (buf[0] & 0x1f) << 8 | buf[1]; 329 #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */ 330 if (tmp) 331 *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24) 332 / 100); 333 else 334 *snr = 0; 335 336 dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr, 337 tmp); 338 339 return ret; 340error: 341 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 342 return ret; 343} 344 345int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks) 346{ 347 *ucblocks = 0; 348 /* no way to read ? */ 349 return 0; 350} 351 352int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status) 353{ 354 struct cxd2820r_priv *priv = fe->demodulator_priv; 355 int ret; 356 u8 buf[4]; 357 *status = 0; 358 359 ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]); 360 if (ret) 361 goto error; 362 363 if ((buf[0] & 0x07) == 6) { 364 ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]); 365 if (ret) 366 goto error; 367 368 if (((buf[1] >> 3) & 0x01) == 1) { 369 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 370 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 371 } else { 372 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 373 FE_HAS_VITERBI | FE_HAS_SYNC; 374 } 375 } else { 376 ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]); 377 if (ret) 378 goto error; 379 380 if ((buf[2] & 0x0f) >= 4) { 381 ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]); 382 if (ret) 383 goto error; 384 385 if (((buf[3] >> 4) & 0x01) == 1) 386 *status |= FE_HAS_SIGNAL; 387 } 388 } 389 390 dev_dbg(&priv->i2c->dev, "%s: lock=%*ph\n", __func__, 4, buf); 391 392 return ret; 393error: 394 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 395 return ret; 396} 397 398int cxd2820r_init_t(struct dvb_frontend *fe) 399{ 400 struct cxd2820r_priv *priv = fe->demodulator_priv; 401 int ret; 402 403 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07); 404 if (ret) 405 goto error; 406 407 return ret; 408error: 409 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 410 return ret; 411} 412 413int cxd2820r_sleep_t(struct dvb_frontend *fe) 414{ 415 struct cxd2820r_priv *priv = fe->demodulator_priv; 416 int ret, i; 417 struct reg_val_mask tab[] = { 418 { 0x000ff, 0x1f, 0xff }, 419 { 0x00085, 0x00, 0xff }, 420 { 0x00088, 0x01, 0xff }, 421 { 0x00081, 0x00, 0xff }, 422 { 0x00080, 0x00, 0xff }, 423 }; 424 425 dev_dbg(&priv->i2c->dev, "%s\n", __func__); 426 427 priv->delivery_system = SYS_UNDEFINED; 428 429 for (i = 0; i < ARRAY_SIZE(tab); i++) { 430 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, 431 tab[i].mask); 432 if (ret) 433 goto error; 434 } 435 436 return ret; 437error: 438 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 439 return ret; 440} 441 442int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe, 443 struct dvb_frontend_tune_settings *s) 444{ 445 s->min_delay_ms = 500; 446 s->step_size = fe->ops.info.frequency_stepsize * 2; 447 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; 448 449 return 0; 450} 451