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 24 int cxd2820r_set_frontend_t(struct dvb_frontend *fe) 25 { 26 struct cxd2820r_priv *priv = fe->demodulator_priv; 27 struct i2c_client *client = priv->client[0]; 28 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 29 int ret, bw_i; 30 unsigned int utmp; 31 u32 if_frequency; 32 u8 buf[3], bw_param; 33 u8 bw_params1[][5] = { 34 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */ 35 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */ 36 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */ 37 }; 38 u8 bw_params2[][2] = { 39 { 0x1f, 0xdc }, /* 6 MHz */ 40 { 0x12, 0xf8 }, /* 7 MHz */ 41 { 0x01, 0xe0 }, /* 8 MHz */ 42 }; 43 struct reg_val_mask tab[] = { 44 { 0x00080, 0x00, 0xff }, 45 { 0x00081, 0x03, 0xff }, 46 { 0x00085, 0x07, 0xff }, 47 { 0x00088, 0x01, 0xff }, 48 49 { 0x00070, priv->ts_mode, 0xff }, 50 { 0x00071, !priv->ts_clk_inv << 4, 0x10 }, 51 { 0x000cb, priv->if_agc_polarity << 6, 0x40 }, 52 { 0x000a5, 0x00, 0x01 }, 53 { 0x00082, 0x20, 0x60 }, 54 { 0x000c2, 0xc3, 0xff }, 55 { 0x0016a, 0x50, 0xff }, 56 { 0x00427, 0x41, 0xff }, 57 }; 58 59 dev_dbg(&client->dev, 60 "delivery_system=%d modulation=%d frequency=%u bandwidth_hz=%u inversion=%d\n", 61 c->delivery_system, c->modulation, c->frequency, 62 c->bandwidth_hz, c->inversion); 63 64 switch (c->bandwidth_hz) { 65 case 6000000: 66 bw_i = 0; 67 bw_param = 2; 68 break; 69 case 7000000: 70 bw_i = 1; 71 bw_param = 1; 72 break; 73 case 8000000: 74 bw_i = 2; 75 bw_param = 0; 76 break; 77 default: 78 return -EINVAL; 79 } 80 81 /* program tuner */ 82 if (fe->ops.tuner_ops.set_params) 83 fe->ops.tuner_ops.set_params(fe); 84 85 if (priv->delivery_system != SYS_DVBT) { 86 ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); 87 if (ret) 88 goto error; 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_frequency); 97 if (ret) 98 goto error; 99 dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency); 100 } else { 101 ret = -EINVAL; 102 goto error; 103 } 104 105 utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK); 106 buf[0] = (utmp >> 16) & 0xff; 107 buf[1] = (utmp >> 8) & 0xff; 108 buf[2] = (utmp >> 0) & 0xff; 109 ret = regmap_bulk_write(priv->regmap[0], 0x00b6, buf, 3); 110 if (ret) 111 goto error; 112 113 ret = regmap_bulk_write(priv->regmap[0], 0x009f, bw_params1[bw_i], 5); 114 if (ret) 115 goto error; 116 117 ret = regmap_update_bits(priv->regmap[0], 0x00d7, 0xc0, bw_param << 6); 118 if (ret) 119 goto error; 120 121 ret = regmap_bulk_write(priv->regmap[0], 0x00d9, bw_params2[bw_i], 2); 122 if (ret) 123 goto error; 124 125 ret = regmap_write(priv->regmap[0], 0x00ff, 0x08); 126 if (ret) 127 goto error; 128 129 ret = regmap_write(priv->regmap[0], 0x00fe, 0x01); 130 if (ret) 131 goto error; 132 133 return ret; 134 error: 135 dev_dbg(&client->dev, "failed=%d\n", ret); 136 return ret; 137 } 138 139 int cxd2820r_get_frontend_t(struct dvb_frontend *fe, 140 struct dtv_frontend_properties *c) 141 { 142 struct cxd2820r_priv *priv = fe->demodulator_priv; 143 struct i2c_client *client = priv->client[0]; 144 int ret; 145 unsigned int utmp; 146 u8 buf[2]; 147 148 dev_dbg(&client->dev, "\n"); 149 150 ret = regmap_bulk_read(priv->regmap[0], 0x002f, buf, sizeof(buf)); 151 if (ret) 152 goto error; 153 154 switch ((buf[0] >> 6) & 0x03) { 155 case 0: 156 c->modulation = QPSK; 157 break; 158 case 1: 159 c->modulation = QAM_16; 160 break; 161 case 2: 162 c->modulation = QAM_64; 163 break; 164 } 165 166 switch ((buf[1] >> 1) & 0x03) { 167 case 0: 168 c->transmission_mode = TRANSMISSION_MODE_2K; 169 break; 170 case 1: 171 c->transmission_mode = TRANSMISSION_MODE_8K; 172 break; 173 } 174 175 switch ((buf[1] >> 3) & 0x03) { 176 case 0: 177 c->guard_interval = GUARD_INTERVAL_1_32; 178 break; 179 case 1: 180 c->guard_interval = GUARD_INTERVAL_1_16; 181 break; 182 case 2: 183 c->guard_interval = GUARD_INTERVAL_1_8; 184 break; 185 case 3: 186 c->guard_interval = GUARD_INTERVAL_1_4; 187 break; 188 } 189 190 switch ((buf[0] >> 3) & 0x07) { 191 case 0: 192 c->hierarchy = HIERARCHY_NONE; 193 break; 194 case 1: 195 c->hierarchy = HIERARCHY_1; 196 break; 197 case 2: 198 c->hierarchy = HIERARCHY_2; 199 break; 200 case 3: 201 c->hierarchy = HIERARCHY_4; 202 break; 203 } 204 205 switch ((buf[0] >> 0) & 0x07) { 206 case 0: 207 c->code_rate_HP = FEC_1_2; 208 break; 209 case 1: 210 c->code_rate_HP = FEC_2_3; 211 break; 212 case 2: 213 c->code_rate_HP = FEC_3_4; 214 break; 215 case 3: 216 c->code_rate_HP = FEC_5_6; 217 break; 218 case 4: 219 c->code_rate_HP = FEC_7_8; 220 break; 221 } 222 223 switch ((buf[1] >> 5) & 0x07) { 224 case 0: 225 c->code_rate_LP = FEC_1_2; 226 break; 227 case 1: 228 c->code_rate_LP = FEC_2_3; 229 break; 230 case 2: 231 c->code_rate_LP = FEC_3_4; 232 break; 233 case 3: 234 c->code_rate_LP = FEC_5_6; 235 break; 236 case 4: 237 c->code_rate_LP = FEC_7_8; 238 break; 239 } 240 241 ret = regmap_read(priv->regmap[0], 0x07c6, &utmp); 242 if (ret) 243 goto error; 244 245 switch ((utmp >> 0) & 0x01) { 246 case 0: 247 c->inversion = INVERSION_OFF; 248 break; 249 case 1: 250 c->inversion = INVERSION_ON; 251 break; 252 } 253 254 return ret; 255 error: 256 dev_dbg(&client->dev, "failed=%d\n", ret); 257 return ret; 258 } 259 260 int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status) 261 { 262 struct cxd2820r_priv *priv = fe->demodulator_priv; 263 struct i2c_client *client = priv->client[0]; 264 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 265 int ret; 266 unsigned int utmp, utmp1, utmp2; 267 u8 buf[3]; 268 269 /* Lock detection */ 270 ret = regmap_bulk_read(priv->regmap[0], 0x0010, &buf[0], 1); 271 if (ret) 272 goto error; 273 ret = regmap_bulk_read(priv->regmap[0], 0x0073, &buf[1], 1); 274 if (ret) 275 goto error; 276 277 utmp1 = (buf[0] >> 0) & 0x07; 278 utmp2 = (buf[1] >> 3) & 0x01; 279 280 if (utmp1 == 6 && utmp2 == 1) { 281 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | 282 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 283 } else if (utmp1 == 6 || utmp2 == 1) { 284 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | 285 FE_HAS_VITERBI | FE_HAS_SYNC; 286 } else { 287 *status = 0; 288 } 289 290 dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n", 291 *status, 2, buf, utmp1, utmp2); 292 293 /* Signal strength */ 294 if (*status & FE_HAS_SIGNAL) { 295 unsigned int strength; 296 297 ret = regmap_bulk_read(priv->regmap[0], 0x0026, buf, 2); 298 if (ret) 299 goto error; 300 301 utmp = buf[0] << 8 | buf[1] << 0; 302 utmp = ~utmp & 0x0fff; 303 /* Scale value to 0x0000-0xffff */ 304 strength = utmp << 4 | utmp >> 8; 305 306 c->strength.len = 1; 307 c->strength.stat[0].scale = FE_SCALE_RELATIVE; 308 c->strength.stat[0].uvalue = strength; 309 } else { 310 c->strength.len = 1; 311 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 312 } 313 314 /* CNR */ 315 if (*status & FE_HAS_VITERBI) { 316 unsigned int cnr; 317 318 ret = regmap_bulk_read(priv->regmap[0], 0x002c, buf, 2); 319 if (ret) 320 goto error; 321 322 utmp = buf[0] << 8 | buf[1] << 0; 323 if (utmp) 324 cnr = div_u64((u64)(intlog10(utmp) 325 - intlog10(32000 - utmp) + 55532585) 326 * 10000, (1 << 24)); 327 else 328 cnr = 0; 329 330 c->cnr.len = 1; 331 c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 332 c->cnr.stat[0].svalue = cnr; 333 } else { 334 c->cnr.len = 1; 335 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 336 } 337 338 /* BER */ 339 if (*status & FE_HAS_SYNC) { 340 unsigned int post_bit_error; 341 bool start_ber; 342 343 if (priv->ber_running) { 344 ret = regmap_bulk_read(priv->regmap[0], 0x0076, buf, 3); 345 if (ret) 346 goto error; 347 348 if ((buf[2] >> 7) & 0x01) { 349 post_bit_error = buf[2] << 16 | buf[1] << 8 | 350 buf[0] << 0; 351 post_bit_error &= 0x0fffff; 352 start_ber = true; 353 } else { 354 post_bit_error = 0; 355 start_ber = false; 356 } 357 } else { 358 post_bit_error = 0; 359 start_ber = true; 360 } 361 362 if (start_ber) { 363 ret = regmap_write(priv->regmap[0], 0x0079, 0x01); 364 if (ret) 365 goto error; 366 priv->ber_running = true; 367 } 368 369 priv->post_bit_error += post_bit_error; 370 371 c->post_bit_error.len = 1; 372 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 373 c->post_bit_error.stat[0].uvalue = priv->post_bit_error; 374 } else { 375 c->post_bit_error.len = 1; 376 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 377 } 378 379 return ret; 380 error: 381 dev_dbg(&client->dev, "failed=%d\n", ret); 382 return ret; 383 } 384 385 int cxd2820r_init_t(struct dvb_frontend *fe) 386 { 387 struct cxd2820r_priv *priv = fe->demodulator_priv; 388 struct i2c_client *client = priv->client[0]; 389 int ret; 390 391 dev_dbg(&client->dev, "\n"); 392 393 ret = regmap_write(priv->regmap[0], 0x0085, 0x07); 394 if (ret) 395 goto error; 396 397 return ret; 398 error: 399 dev_dbg(&client->dev, "failed=%d\n", ret); 400 return ret; 401 } 402 403 int cxd2820r_sleep_t(struct dvb_frontend *fe) 404 { 405 struct cxd2820r_priv *priv = fe->demodulator_priv; 406 struct i2c_client *client = priv->client[0]; 407 int ret; 408 struct reg_val_mask tab[] = { 409 { 0x000ff, 0x1f, 0xff }, 410 { 0x00085, 0x00, 0xff }, 411 { 0x00088, 0x01, 0xff }, 412 { 0x00081, 0x00, 0xff }, 413 { 0x00080, 0x00, 0xff }, 414 }; 415 416 dev_dbg(&client->dev, "\n"); 417 418 priv->delivery_system = SYS_UNDEFINED; 419 420 ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); 421 if (ret) 422 goto error; 423 424 return ret; 425 error: 426 dev_dbg(&client->dev, "failed=%d\n", ret); 427 return ret; 428 } 429 430 int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe, 431 struct dvb_frontend_tune_settings *s) 432 { 433 s->min_delay_ms = 500; 434 s->step_size = fe->ops.info.frequency_stepsize_hz * 2; 435 s->max_drift = (fe->ops.info.frequency_stepsize_hz * 2) + 1; 436 437 return 0; 438 } 439