1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * ascot2e.c 4 * 5 * Sony Ascot3E DVB-T/T2/C/C2 tuner driver 6 * 7 * Copyright 2012 Sony Corporation 8 * Copyright (C) 2014 NetUP Inc. 9 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru> 10 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru> 11 */ 12 13 #include <linux/slab.h> 14 #include <linux/module.h> 15 #include <linux/dvb/frontend.h> 16 #include <linux/types.h> 17 #include "ascot2e.h" 18 #include <media/dvb_frontend.h> 19 20 #define MAX_WRITE_REGSIZE 10 21 22 enum ascot2e_state { 23 STATE_UNKNOWN, 24 STATE_SLEEP, 25 STATE_ACTIVE 26 }; 27 28 struct ascot2e_priv { 29 u32 frequency; 30 u8 i2c_address; 31 struct i2c_adapter *i2c; 32 enum ascot2e_state state; 33 void *set_tuner_data; 34 int (*set_tuner)(void *, int); 35 }; 36 37 enum ascot2e_tv_system_t { 38 ASCOT2E_DTV_DVBT_5, 39 ASCOT2E_DTV_DVBT_6, 40 ASCOT2E_DTV_DVBT_7, 41 ASCOT2E_DTV_DVBT_8, 42 ASCOT2E_DTV_DVBT2_1_7, 43 ASCOT2E_DTV_DVBT2_5, 44 ASCOT2E_DTV_DVBT2_6, 45 ASCOT2E_DTV_DVBT2_7, 46 ASCOT2E_DTV_DVBT2_8, 47 ASCOT2E_DTV_DVBC_6, 48 ASCOT2E_DTV_DVBC_8, 49 ASCOT2E_DTV_DVBC2_6, 50 ASCOT2E_DTV_DVBC2_8, 51 ASCOT2E_DTV_UNKNOWN 52 }; 53 54 struct ascot2e_band_sett { 55 u8 if_out_sel; 56 u8 agc_sel; 57 u8 mix_oll; 58 u8 rf_gain; 59 u8 if_bpf_gc; 60 u8 fif_offset; 61 u8 bw_offset; 62 u8 bw; 63 u8 rf_oldet; 64 u8 if_bpf_f0; 65 }; 66 67 #define ASCOT2E_AUTO 0xff 68 #define ASCOT2E_OFFSET(ofs) ((u8)(ofs) & 0x1F) 69 #define ASCOT2E_BW_6 0x00 70 #define ASCOT2E_BW_7 0x01 71 #define ASCOT2E_BW_8 0x02 72 #define ASCOT2E_BW_1_7 0x03 73 74 static struct ascot2e_band_sett ascot2e_sett[] = { 75 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 76 ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 }, 77 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 78 ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 }, 79 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 80 ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 }, 81 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 82 ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 }, 83 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 84 ASCOT2E_OFFSET(-10), ASCOT2E_OFFSET(-16), ASCOT2E_BW_1_7, 0x0B, 0x00 }, 85 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 86 ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 }, 87 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 88 ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 }, 89 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 90 ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 }, 91 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06, 92 ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 }, 93 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03, 94 ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-8), ASCOT2E_BW_6, 0x09, 0x00 }, 95 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03, 96 ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(-1), ASCOT2E_BW_8, 0x09, 0x00 }, 97 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01, 98 ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_6, 0x09, 0x00 }, 99 { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01, 100 ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(2), ASCOT2E_BW_8, 0x09, 0x00 } 101 }; 102 103 static void ascot2e_i2c_debug(struct ascot2e_priv *priv, 104 u8 reg, u8 write, const u8 *data, u32 len) 105 { 106 dev_dbg(&priv->i2c->dev, "ascot2e: I2C %s reg 0x%02x size %d\n", 107 (write == 0 ? "read" : "write"), reg, len); 108 print_hex_dump_bytes("ascot2e: I2C data: ", 109 DUMP_PREFIX_OFFSET, data, len); 110 } 111 112 static int ascot2e_write_regs(struct ascot2e_priv *priv, 113 u8 reg, const u8 *data, u32 len) 114 { 115 int ret; 116 u8 buf[MAX_WRITE_REGSIZE + 1]; 117 struct i2c_msg msg[1] = { 118 { 119 .addr = priv->i2c_address, 120 .flags = 0, 121 .len = len + 1, 122 .buf = buf, 123 } 124 }; 125 126 if (len + 1 > sizeof(buf)) { 127 dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n", 128 reg, len + 1); 129 return -E2BIG; 130 } 131 132 ascot2e_i2c_debug(priv, reg, 1, data, len); 133 buf[0] = reg; 134 memcpy(&buf[1], data, len); 135 ret = i2c_transfer(priv->i2c, msg, 1); 136 if (ret >= 0 && ret != 1) 137 ret = -EREMOTEIO; 138 if (ret < 0) { 139 dev_warn(&priv->i2c->dev, 140 "%s: i2c wr failed=%d reg=%02x len=%d\n", 141 KBUILD_MODNAME, ret, reg, len); 142 return ret; 143 } 144 return 0; 145 } 146 147 static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val) 148 { 149 u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ 150 151 return ascot2e_write_regs(priv, reg, &tmp, 1); 152 } 153 154 static int ascot2e_read_regs(struct ascot2e_priv *priv, 155 u8 reg, u8 *val, u32 len) 156 { 157 int ret; 158 struct i2c_msg msg[2] = { 159 { 160 .addr = priv->i2c_address, 161 .flags = 0, 162 .len = 1, 163 .buf = ®, 164 }, { 165 .addr = priv->i2c_address, 166 .flags = I2C_M_RD, 167 .len = len, 168 .buf = val, 169 } 170 }; 171 172 ret = i2c_transfer(priv->i2c, &msg[0], 1); 173 if (ret >= 0 && ret != 1) 174 ret = -EREMOTEIO; 175 if (ret < 0) { 176 dev_warn(&priv->i2c->dev, 177 "%s: I2C rw failed=%d addr=%02x reg=%02x\n", 178 KBUILD_MODNAME, ret, priv->i2c_address, reg); 179 return ret; 180 } 181 ret = i2c_transfer(priv->i2c, &msg[1], 1); 182 if (ret >= 0 && ret != 1) 183 ret = -EREMOTEIO; 184 if (ret < 0) { 185 dev_warn(&priv->i2c->dev, 186 "%s: i2c rd failed=%d addr=%02x reg=%02x\n", 187 KBUILD_MODNAME, ret, priv->i2c_address, reg); 188 return ret; 189 } 190 ascot2e_i2c_debug(priv, reg, 0, val, len); 191 return 0; 192 } 193 194 static int ascot2e_read_reg(struct ascot2e_priv *priv, u8 reg, u8 *val) 195 { 196 return ascot2e_read_regs(priv, reg, val, 1); 197 } 198 199 static int ascot2e_set_reg_bits(struct ascot2e_priv *priv, 200 u8 reg, u8 data, u8 mask) 201 { 202 int res; 203 u8 rdata; 204 205 if (mask != 0xff) { 206 res = ascot2e_read_reg(priv, reg, &rdata); 207 if (res != 0) 208 return res; 209 data = ((data & mask) | (rdata & (mask ^ 0xFF))); 210 } 211 return ascot2e_write_reg(priv, reg, data); 212 } 213 214 static int ascot2e_enter_power_save(struct ascot2e_priv *priv) 215 { 216 u8 data[2]; 217 218 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 219 if (priv->state == STATE_SLEEP) 220 return 0; 221 data[0] = 0x00; 222 data[1] = 0x04; 223 ascot2e_write_regs(priv, 0x14, data, 2); 224 ascot2e_write_reg(priv, 0x50, 0x01); 225 priv->state = STATE_SLEEP; 226 return 0; 227 } 228 229 static int ascot2e_leave_power_save(struct ascot2e_priv *priv) 230 { 231 u8 data[2] = { 0xFB, 0x0F }; 232 233 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 234 if (priv->state == STATE_ACTIVE) 235 return 0; 236 ascot2e_write_regs(priv, 0x14, data, 2); 237 ascot2e_write_reg(priv, 0x50, 0x00); 238 priv->state = STATE_ACTIVE; 239 return 0; 240 } 241 242 static int ascot2e_init(struct dvb_frontend *fe) 243 { 244 struct ascot2e_priv *priv = fe->tuner_priv; 245 246 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 247 return ascot2e_leave_power_save(priv); 248 } 249 250 static void ascot2e_release(struct dvb_frontend *fe) 251 { 252 struct ascot2e_priv *priv = fe->tuner_priv; 253 254 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 255 kfree(fe->tuner_priv); 256 fe->tuner_priv = NULL; 257 } 258 259 static int ascot2e_sleep(struct dvb_frontend *fe) 260 { 261 struct ascot2e_priv *priv = fe->tuner_priv; 262 263 dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 264 ascot2e_enter_power_save(priv); 265 return 0; 266 } 267 268 static enum ascot2e_tv_system_t ascot2e_get_tv_system(struct dvb_frontend *fe) 269 { 270 enum ascot2e_tv_system_t system = ASCOT2E_DTV_UNKNOWN; 271 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 272 struct ascot2e_priv *priv = fe->tuner_priv; 273 274 if (p->delivery_system == SYS_DVBT) { 275 if (p->bandwidth_hz <= 5000000) 276 system = ASCOT2E_DTV_DVBT_5; 277 else if (p->bandwidth_hz <= 6000000) 278 system = ASCOT2E_DTV_DVBT_6; 279 else if (p->bandwidth_hz <= 7000000) 280 system = ASCOT2E_DTV_DVBT_7; 281 else if (p->bandwidth_hz <= 8000000) 282 system = ASCOT2E_DTV_DVBT_8; 283 else { 284 system = ASCOT2E_DTV_DVBT_8; 285 p->bandwidth_hz = 8000000; 286 } 287 } else if (p->delivery_system == SYS_DVBT2) { 288 if (p->bandwidth_hz <= 5000000) 289 system = ASCOT2E_DTV_DVBT2_5; 290 else if (p->bandwidth_hz <= 6000000) 291 system = ASCOT2E_DTV_DVBT2_6; 292 else if (p->bandwidth_hz <= 7000000) 293 system = ASCOT2E_DTV_DVBT2_7; 294 else if (p->bandwidth_hz <= 8000000) 295 system = ASCOT2E_DTV_DVBT2_8; 296 else { 297 system = ASCOT2E_DTV_DVBT2_8; 298 p->bandwidth_hz = 8000000; 299 } 300 } else if (p->delivery_system == SYS_DVBC_ANNEX_A) { 301 if (p->bandwidth_hz <= 6000000) 302 system = ASCOT2E_DTV_DVBC_6; 303 else if (p->bandwidth_hz <= 8000000) 304 system = ASCOT2E_DTV_DVBC_8; 305 } 306 dev_dbg(&priv->i2c->dev, 307 "%s(): ASCOT2E DTV system %d (delsys %d, bandwidth %d)\n", 308 __func__, (int)system, p->delivery_system, p->bandwidth_hz); 309 return system; 310 } 311 312 static int ascot2e_set_params(struct dvb_frontend *fe) 313 { 314 u8 data[10]; 315 u32 frequency; 316 enum ascot2e_tv_system_t tv_system; 317 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 318 struct ascot2e_priv *priv = fe->tuner_priv; 319 320 dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n", 321 __func__, p->frequency / 1000); 322 tv_system = ascot2e_get_tv_system(fe); 323 324 if (tv_system == ASCOT2E_DTV_UNKNOWN) { 325 dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n", 326 __func__); 327 return -EINVAL; 328 } 329 if (priv->set_tuner) 330 priv->set_tuner(priv->set_tuner_data, 1); 331 frequency = roundup(p->frequency / 1000, 25); 332 if (priv->state == STATE_SLEEP) 333 ascot2e_leave_power_save(priv); 334 335 /* IF_OUT_SEL / AGC_SEL setting */ 336 data[0] = 0x00; 337 if (ascot2e_sett[tv_system].agc_sel != ASCOT2E_AUTO) { 338 /* AGC pin setting from parameter table */ 339 data[0] |= (u8)( 340 (ascot2e_sett[tv_system].agc_sel & 0x03) << 3); 341 } 342 if (ascot2e_sett[tv_system].if_out_sel != ASCOT2E_AUTO) { 343 /* IFOUT pin setting from parameter table */ 344 data[0] |= (u8)( 345 (ascot2e_sett[tv_system].if_out_sel & 0x01) << 2); 346 } 347 /* Set bit[4:2] only */ 348 ascot2e_set_reg_bits(priv, 0x05, data[0], 0x1c); 349 /* 0x06 - 0x0F */ 350 /* REF_R setting (0x06) */ 351 if (tv_system == ASCOT2E_DTV_DVBC_6 || 352 tv_system == ASCOT2E_DTV_DVBC_8) { 353 /* xtal, xtal*2 */ 354 data[0] = (frequency > 500000) ? 16 : 32; 355 } else { 356 /* xtal/8, xtal/4 */ 357 data[0] = (frequency > 500000) ? 2 : 4; 358 } 359 /* XOSC_SEL=100uA */ 360 data[1] = 0x04; 361 /* KBW setting (0x08), KC0 setting (0x09), KC1 setting (0x0A) */ 362 if (tv_system == ASCOT2E_DTV_DVBC_6 || 363 tv_system == ASCOT2E_DTV_DVBC_8) { 364 data[2] = 18; 365 data[3] = 120; 366 data[4] = 20; 367 } else { 368 data[2] = 48; 369 data[3] = 10; 370 data[4] = 30; 371 } 372 /* ORDER/R2_RANGE/R2_BANK/C2_BANK setting (0x0B) */ 373 if (tv_system == ASCOT2E_DTV_DVBC_6 || 374 tv_system == ASCOT2E_DTV_DVBC_8) 375 data[5] = (frequency > 500000) ? 0x08 : 0x0c; 376 else 377 data[5] = (frequency > 500000) ? 0x30 : 0x38; 378 /* Set MIX_OLL (0x0C) value from parameter table */ 379 data[6] = ascot2e_sett[tv_system].mix_oll; 380 /* Set RF_GAIN (0x0D) setting from parameter table */ 381 if (ascot2e_sett[tv_system].rf_gain == ASCOT2E_AUTO) { 382 /* RF_GAIN auto control enable */ 383 ascot2e_write_reg(priv, 0x4E, 0x01); 384 /* RF_GAIN Default value */ 385 data[7] = 0x00; 386 } else { 387 /* RF_GAIN auto control disable */ 388 ascot2e_write_reg(priv, 0x4E, 0x00); 389 data[7] = ascot2e_sett[tv_system].rf_gain; 390 } 391 /* Set IF_BPF_GC/FIF_OFFSET (0x0E) value from parameter table */ 392 data[8] = (u8)((ascot2e_sett[tv_system].fif_offset << 3) | 393 (ascot2e_sett[tv_system].if_bpf_gc & 0x07)); 394 /* Set BW_OFFSET (0x0F) value from parameter table */ 395 data[9] = ascot2e_sett[tv_system].bw_offset; 396 ascot2e_write_regs(priv, 0x06, data, 10); 397 /* 398 * 0x45 - 0x47 399 * LNA optimization setting 400 * RF_LNA_DIST1-5, RF_LNA_CM 401 */ 402 if (tv_system == ASCOT2E_DTV_DVBC_6 || 403 tv_system == ASCOT2E_DTV_DVBC_8) { 404 data[0] = 0x0F; 405 data[1] = 0x00; 406 data[2] = 0x01; 407 } else { 408 data[0] = 0x0F; 409 data[1] = 0x00; 410 data[2] = 0x03; 411 } 412 ascot2e_write_regs(priv, 0x45, data, 3); 413 /* 0x49 - 0x4A 414 Set RF_OLDET_ENX/RF_OLDET_OLL value from parameter table */ 415 data[0] = ascot2e_sett[tv_system].rf_oldet; 416 /* Set IF_BPF_F0 value from parameter table */ 417 data[1] = ascot2e_sett[tv_system].if_bpf_f0; 418 ascot2e_write_regs(priv, 0x49, data, 2); 419 /* 420 * Tune now 421 * RFAGC fast mode / RFAGC auto control enable 422 * (set bit[7], bit[5:4] only) 423 * vco_cal = 1, set MIX_OL_CPU_EN 424 */ 425 ascot2e_set_reg_bits(priv, 0x0c, 0x90, 0xb0); 426 /* Logic wake up, CPU wake up */ 427 data[0] = 0xc4; 428 data[1] = 0x40; 429 ascot2e_write_regs(priv, 0x03, data, 2); 430 /* 0x10 - 0x14 */ 431 data[0] = (u8)(frequency & 0xFF); /* 0x10: FRF_L */ 432 data[1] = (u8)((frequency >> 8) & 0xFF); /* 0x11: FRF_M */ 433 data[2] = (u8)((frequency >> 16) & 0x0F); /* 0x12: FRF_H (bit[3:0]) */ 434 /* 0x12: BW (bit[5:4]) */ 435 data[2] |= (u8)(ascot2e_sett[tv_system].bw << 4); 436 data[3] = 0xFF; /* 0x13: VCO calibration enable */ 437 data[4] = 0xFF; /* 0x14: Analog block enable */ 438 /* Tune (Burst write) */ 439 ascot2e_write_regs(priv, 0x10, data, 5); 440 msleep(50); 441 /* CPU deep sleep */ 442 ascot2e_write_reg(priv, 0x04, 0x00); 443 /* Logic sleep */ 444 ascot2e_write_reg(priv, 0x03, 0xC0); 445 /* RFAGC normal mode (set bit[5:4] only) */ 446 ascot2e_set_reg_bits(priv, 0x0C, 0x00, 0x30); 447 priv->frequency = frequency; 448 return 0; 449 } 450 451 static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency) 452 { 453 struct ascot2e_priv *priv = fe->tuner_priv; 454 455 *frequency = priv->frequency * 1000; 456 return 0; 457 } 458 459 static const struct dvb_tuner_ops ascot2e_tuner_ops = { 460 .info = { 461 .name = "Sony ASCOT2E", 462 .frequency_min_hz = 1 * MHz, 463 .frequency_max_hz = 1200 * MHz, 464 .frequency_step_hz = 25 * kHz, 465 }, 466 .init = ascot2e_init, 467 .release = ascot2e_release, 468 .sleep = ascot2e_sleep, 469 .set_params = ascot2e_set_params, 470 .get_frequency = ascot2e_get_frequency, 471 }; 472 473 struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe, 474 const struct ascot2e_config *config, 475 struct i2c_adapter *i2c) 476 { 477 u8 data[4]; 478 struct ascot2e_priv *priv = NULL; 479 480 priv = kzalloc(sizeof(struct ascot2e_priv), GFP_KERNEL); 481 if (priv == NULL) 482 return NULL; 483 priv->i2c_address = (config->i2c_address >> 1); 484 priv->i2c = i2c; 485 priv->set_tuner_data = config->set_tuner_priv; 486 priv->set_tuner = config->set_tuner_callback; 487 488 if (fe->ops.i2c_gate_ctrl) 489 fe->ops.i2c_gate_ctrl(fe, 1); 490 491 /* 16 MHz xTal frequency */ 492 data[0] = 16; 493 /* VCO current setting */ 494 data[1] = 0x06; 495 /* Logic wake up, CPU boot */ 496 data[2] = 0xC4; 497 data[3] = 0x40; 498 ascot2e_write_regs(priv, 0x01, data, 4); 499 /* RFVGA optimization setting (RF_DIST0 - RF_DIST2) */ 500 data[0] = 0x10; 501 data[1] = 0x3F; 502 data[2] = 0x25; 503 ascot2e_write_regs(priv, 0x22, data, 3); 504 /* PLL mode setting */ 505 ascot2e_write_reg(priv, 0x28, 0x1e); 506 /* RSSI setting */ 507 ascot2e_write_reg(priv, 0x59, 0x04); 508 /* TODO check CPU HW error state here */ 509 msleep(80); 510 /* Xtal oscillator current control setting */ 511 ascot2e_write_reg(priv, 0x4c, 0x01); 512 /* XOSC_SEL=100uA */ 513 ascot2e_write_reg(priv, 0x07, 0x04); 514 /* CPU deep sleep */ 515 ascot2e_write_reg(priv, 0x04, 0x00); 516 /* Logic sleep */ 517 ascot2e_write_reg(priv, 0x03, 0xc0); 518 /* Power save setting */ 519 data[0] = 0x00; 520 data[1] = 0x04; 521 ascot2e_write_regs(priv, 0x14, data, 2); 522 ascot2e_write_reg(priv, 0x50, 0x01); 523 priv->state = STATE_SLEEP; 524 525 if (fe->ops.i2c_gate_ctrl) 526 fe->ops.i2c_gate_ctrl(fe, 0); 527 528 memcpy(&fe->ops.tuner_ops, &ascot2e_tuner_ops, 529 sizeof(struct dvb_tuner_ops)); 530 fe->tuner_priv = priv; 531 dev_info(&priv->i2c->dev, 532 "Sony ASCOT2E attached on addr=%x at I2C adapter %p\n", 533 priv->i2c_address, priv->i2c); 534 return fe; 535 } 536 EXPORT_SYMBOL(ascot2e_attach); 537 538 MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver"); 539 MODULE_AUTHOR("info@netup.ru"); 540 MODULE_LICENSE("GPL"); 541