root/drivers/media/common/b2c2/flexcop-fe-tuner.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. flexcop_fe_request_firmware
  2. flexcop_set_voltage
  3. flexcop_sleep
  4. flexcop_set_tone
  5. flexcop_diseqc_send_bit
  6. flexcop_diseqc_send_byte
  7. flexcop_send_diseqc_msg
  8. flexcop_diseqc_send_master_cmd
  9. flexcop_diseqc_send_burst
  10. skystar2_rev23_attach
  11. samsung_tbmu24112_set_symbol_rate
  12. skystar2_rev26_attach
  13. skystar2_rev27_attach
  14. skystar2_rev28_attach
  15. samsung_tdtc9251dh0_demod_init
  16. airstar_dvbt_attach
  17. airstar_atsc1_attach
  18. airstar_atsc2_attach
  19. airstar_atsc3_attach
  20. cablestar2_attach
  21. skystarS2_rev33_attach
  22. flexcop_frontend_init
  23. flexcop_frontend_exit

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
   4  * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
   5  * see flexcop.c for copyright information
   6  */
   7 #include <media/tuner.h>
   8 #include "flexcop.h"
   9 #include "mt312.h"
  10 #include "stv0299.h"
  11 #include "s5h1420.h"
  12 #include "itd1000.h"
  13 #include "cx24113.h"
  14 #include "cx24123.h"
  15 #include "isl6421.h"
  16 #include "cx24120.h"
  17 #include "mt352.h"
  18 #include "bcm3510.h"
  19 #include "nxt200x.h"
  20 #include "dvb-pll.h"
  21 #include "lgdt330x.h"
  22 #include "tuner-simple.h"
  23 #include "stv0297.h"
  24 
  25 
  26 /* Can we use the specified front-end?  Remember that if we are compiled
  27  * into the kernel we can't call code that's in modules.  */
  28 #define FE_SUPPORTED(fe) IS_REACHABLE(CONFIG_DVB_ ## fe)
  29 
  30 #if FE_SUPPORTED(BCM3510) || (FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421))
  31 static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
  32         const struct firmware **fw, char *name)
  33 {
  34         struct flexcop_device *fc = fe->dvb->priv;
  35 
  36         return request_firmware(fw, name, fc->dev);
  37 }
  38 #endif
  39 
  40 /* lnb control */
  41 #if (FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)) && FE_SUPPORTED(PLL)
  42 static int flexcop_set_voltage(struct dvb_frontend *fe,
  43                                enum fe_sec_voltage voltage)
  44 {
  45         struct flexcop_device *fc = fe->dvb->priv;
  46         flexcop_ibi_value v;
  47         deb_tuner("polarity/voltage = %u\n", voltage);
  48 
  49         v = fc->read_ibi_reg(fc, misc_204);
  50         switch (voltage) {
  51         case SEC_VOLTAGE_OFF:
  52                 v.misc_204.ACPI1_sig = 1;
  53                 break;
  54         case SEC_VOLTAGE_13:
  55                 v.misc_204.ACPI1_sig = 0;
  56                 v.misc_204.LNB_L_H_sig = 0;
  57                 break;
  58         case SEC_VOLTAGE_18:
  59                 v.misc_204.ACPI1_sig = 0;
  60                 v.misc_204.LNB_L_H_sig = 1;
  61                 break;
  62         default:
  63                 err("unknown SEC_VOLTAGE value");
  64                 return -EINVAL;
  65         }
  66         return fc->write_ibi_reg(fc, misc_204, v);
  67 }
  68 #endif
  69 
  70 #if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
  71 static int __maybe_unused flexcop_sleep(struct dvb_frontend* fe)
  72 {
  73         struct flexcop_device *fc = fe->dvb->priv;
  74         if (fc->fe_sleep)
  75                 return fc->fe_sleep(fe);
  76         return 0;
  77 }
  78 #endif
  79 
  80 /* SkyStar2 DVB-S rev 2.3 */
  81 #if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
  82 static int flexcop_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
  83 {
  84 /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
  85         struct flexcop_device *fc = fe->dvb->priv;
  86         flexcop_ibi_value v;
  87         u16 ax;
  88         v.raw = 0;
  89         deb_tuner("tone = %u\n",tone);
  90 
  91         switch (tone) {
  92         case SEC_TONE_ON:
  93                 ax = 0x01ff;
  94                 break;
  95         case SEC_TONE_OFF:
  96                 ax = 0;
  97                 break;
  98         default:
  99                 err("unknown SEC_TONE value");
 100                 return -EINVAL;
 101         }
 102 
 103         v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
 104         v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
 105         v.lnb_switch_freq_200.LNB_CTLLowCount_sig  = ax == 0 ? 0x1ff : ax;
 106         return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
 107 }
 108 
 109 static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
 110 {
 111         flexcop_set_tone(fe, SEC_TONE_ON);
 112         udelay(data ? 500 : 1000);
 113         flexcop_set_tone(fe, SEC_TONE_OFF);
 114         udelay(data ? 1000 : 500);
 115 }
 116 
 117 static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
 118 {
 119         int i, par = 1, d;
 120         for (i = 7; i >= 0; i--) {
 121                 d = (data >> i) & 1;
 122                 par ^= d;
 123                 flexcop_diseqc_send_bit(fe, d);
 124         }
 125         flexcop_diseqc_send_bit(fe, par);
 126 }
 127 
 128 static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
 129         int len, u8 *msg, unsigned long burst)
 130 {
 131         int i;
 132 
 133         flexcop_set_tone(fe, SEC_TONE_OFF);
 134         mdelay(16);
 135 
 136         for (i = 0; i < len; i++)
 137                 flexcop_diseqc_send_byte(fe,msg[i]);
 138         mdelay(16);
 139 
 140         if (burst != -1) {
 141                 if (burst)
 142                         flexcop_diseqc_send_byte(fe, 0xff);
 143                 else {
 144                         flexcop_set_tone(fe, SEC_TONE_ON);
 145                         mdelay(12);
 146                         udelay(500);
 147                         flexcop_set_tone(fe, SEC_TONE_OFF);
 148                 }
 149                 msleep(20);
 150         }
 151         return 0;
 152 }
 153 
 154 static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
 155         struct dvb_diseqc_master_cmd *cmd)
 156 {
 157         return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
 158 }
 159 
 160 static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
 161                                      enum fe_sec_mini_cmd minicmd)
 162 {
 163         return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
 164 }
 165 
 166 static struct mt312_config skystar23_samsung_tbdu18132_config = {
 167         .demod_address = 0x0e,
 168 };
 169 
 170 static int skystar2_rev23_attach(struct flexcop_device *fc,
 171         struct i2c_adapter *i2c)
 172 {
 173         struct dvb_frontend_ops *ops;
 174 
 175         fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
 176         if (!fc->fe)
 177                 return 0;
 178 
 179         if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
 180                         DVB_PLL_SAMSUNG_TBDU18132))
 181                 return 0;
 182 
 183         ops = &fc->fe->ops;
 184         ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
 185         ops->diseqc_send_burst      = flexcop_diseqc_send_burst;
 186         ops->set_tone               = flexcop_set_tone;
 187         ops->set_voltage            = flexcop_set_voltage;
 188         fc->fe_sleep                = ops->sleep;
 189         ops->sleep                  = flexcop_sleep;
 190         return 1;
 191 }
 192 #else
 193 #define skystar2_rev23_attach NULL
 194 #endif
 195 
 196 /* SkyStar2 DVB-S rev 2.6 */
 197 #if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
 198 static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
 199         u32 srate, u32 ratio)
 200 {
 201         u8 aclk = 0;
 202         u8 bclk = 0;
 203 
 204         if (srate < 1500000) {
 205                 aclk = 0xb7; bclk = 0x47;
 206         } else if (srate < 3000000) {
 207                 aclk = 0xb7; bclk = 0x4b;
 208         } else if (srate < 7000000) {
 209                 aclk = 0xb7; bclk = 0x4f;
 210         } else if (srate < 14000000) {
 211                 aclk = 0xb7; bclk = 0x53;
 212         } else if (srate < 30000000) {
 213                 aclk = 0xb6; bclk = 0x53;
 214         } else if (srate < 45000000) {
 215                 aclk = 0xb4; bclk = 0x51;
 216         }
 217 
 218         stv0299_writereg(fe, 0x13, aclk);
 219         stv0299_writereg(fe, 0x14, bclk);
 220         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 221         stv0299_writereg(fe, 0x20, (ratio >>  8) & 0xff);
 222         stv0299_writereg(fe, 0x21,  ratio        & 0xf0);
 223         return 0;
 224 }
 225 
 226 static u8 samsung_tbmu24112_inittab[] = {
 227         0x01, 0x15,
 228         0x02, 0x30,
 229         0x03, 0x00,
 230         0x04, 0x7D,
 231         0x05, 0x35,
 232         0x06, 0x02,
 233         0x07, 0x00,
 234         0x08, 0xC3,
 235         0x0C, 0x00,
 236         0x0D, 0x81,
 237         0x0E, 0x23,
 238         0x0F, 0x12,
 239         0x10, 0x7E,
 240         0x11, 0x84,
 241         0x12, 0xB9,
 242         0x13, 0x88,
 243         0x14, 0x89,
 244         0x15, 0xC9,
 245         0x16, 0x00,
 246         0x17, 0x5C,
 247         0x18, 0x00,
 248         0x19, 0x00,
 249         0x1A, 0x00,
 250         0x1C, 0x00,
 251         0x1D, 0x00,
 252         0x1E, 0x00,
 253         0x1F, 0x3A,
 254         0x20, 0x2E,
 255         0x21, 0x80,
 256         0x22, 0xFF,
 257         0x23, 0xC1,
 258         0x28, 0x00,
 259         0x29, 0x1E,
 260         0x2A, 0x14,
 261         0x2B, 0x0F,
 262         0x2C, 0x09,
 263         0x2D, 0x05,
 264         0x31, 0x1F,
 265         0x32, 0x19,
 266         0x33, 0xFE,
 267         0x34, 0x93,
 268         0xff, 0xff,
 269 };
 270 
 271 static struct stv0299_config samsung_tbmu24112_config = {
 272         .demod_address = 0x68,
 273         .inittab = samsung_tbmu24112_inittab,
 274         .mclk = 88000000UL,
 275         .invert = 0,
 276         .skip_reinit = 0,
 277         .lock_output = STV0299_LOCKOUTPUT_LK,
 278         .volt13_op0_op1 = STV0299_VOLT13_OP1,
 279         .min_delay_ms = 100,
 280         .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
 281 };
 282 
 283 static int skystar2_rev26_attach(struct flexcop_device *fc,
 284         struct i2c_adapter *i2c)
 285 {
 286         fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
 287         if (!fc->fe)
 288                 return 0;
 289 
 290         if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
 291                         DVB_PLL_SAMSUNG_TBMU24112))
 292                 return 0;
 293 
 294         fc->fe->ops.set_voltage = flexcop_set_voltage;
 295         fc->fe_sleep = fc->fe->ops.sleep;
 296         fc->fe->ops.sleep = flexcop_sleep;
 297         return 1;
 298 
 299 }
 300 #else
 301 #define skystar2_rev26_attach NULL
 302 #endif
 303 
 304 /* SkyStar2 DVB-S rev 2.7 */
 305 #if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
 306 static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
 307         .demod_address = 0x53,
 308         .invert = 1,
 309         .repeated_start_workaround = 1,
 310         .serial_mpeg = 1,
 311 };
 312 
 313 static struct itd1000_config skystar2_rev2_7_itd1000_config = {
 314         .i2c_address = 0x61,
 315 };
 316 
 317 static int skystar2_rev27_attach(struct flexcop_device *fc,
 318         struct i2c_adapter *i2c)
 319 {
 320         flexcop_ibi_value r108;
 321         struct i2c_adapter *i2c_tuner;
 322 
 323         /* enable no_base_addr - no repeated start when reading */
 324         fc->fc_i2c_adap[0].no_base_addr = 1;
 325         fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
 326                             i2c);
 327         if (!fc->fe)
 328                 goto fail;
 329 
 330         i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
 331         if (!i2c_tuner)
 332                 goto fail;
 333 
 334         fc->fe_sleep = fc->fe->ops.sleep;
 335         fc->fe->ops.sleep = flexcop_sleep;
 336 
 337         /* enable no_base_addr - no repeated start when reading */
 338         fc->fc_i2c_adap[2].no_base_addr = 1;
 339         if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
 340                         0x08, 1, 1, false)) {
 341                 err("ISL6421 could NOT be attached");
 342                 goto fail_isl;
 343         }
 344         info("ISL6421 successfully attached");
 345 
 346         /* the ITD1000 requires a lower i2c clock - is it a problem ? */
 347         r108.raw = 0x00000506;
 348         fc->write_ibi_reg(fc, tw_sm_c_108, r108);
 349         if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
 350                         &skystar2_rev2_7_itd1000_config)) {
 351                 err("ITD1000 could NOT be attached");
 352                 /* Should i2c clock be restored? */
 353                 goto fail_isl;
 354         }
 355         info("ITD1000 successfully attached");
 356 
 357         return 1;
 358 
 359 fail_isl:
 360         fc->fc_i2c_adap[2].no_base_addr = 0;
 361 fail:
 362         /* for the next devices we need it again */
 363         fc->fc_i2c_adap[0].no_base_addr = 0;
 364         return 0;
 365 }
 366 #else
 367 #define skystar2_rev27_attach NULL
 368 #endif
 369 
 370 /* SkyStar2 rev 2.8 */
 371 #if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
 372 static struct cx24123_config skystar2_rev2_8_cx24123_config = {
 373         .demod_address = 0x55,
 374         .dont_use_pll = 1,
 375         .agc_callback = cx24113_agc_callback,
 376 };
 377 
 378 static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
 379         .i2c_addr = 0x54,
 380         .xtal_khz = 10111,
 381 };
 382 
 383 static int skystar2_rev28_attach(struct flexcop_device *fc,
 384         struct i2c_adapter *i2c)
 385 {
 386         struct i2c_adapter *i2c_tuner;
 387 
 388         fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
 389                             i2c);
 390         if (!fc->fe)
 391                 return 0;
 392 
 393         i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
 394         if (!i2c_tuner)
 395                 return 0;
 396 
 397         if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
 398                         i2c_tuner)) {
 399                 err("CX24113 could NOT be attached");
 400                 return 0;
 401         }
 402         info("CX24113 successfully attached");
 403 
 404         fc->fc_i2c_adap[2].no_base_addr = 1;
 405         if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
 406                         0x08, 0, 0, false)) {
 407                 err("ISL6421 could NOT be attached");
 408                 fc->fc_i2c_adap[2].no_base_addr = 0;
 409                 return 0;
 410         }
 411         info("ISL6421 successfully attached");
 412         /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
 413          * IR-receiver (PIC16F818) - but the card has no input for that ??? */
 414         return 1;
 415 }
 416 #else
 417 #define skystar2_rev28_attach NULL
 418 #endif
 419 
 420 /* AirStar DVB-T */
 421 #if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
 422 static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
 423 {
 424         static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
 425         static u8 mt352_reset[] = { 0x50, 0x80 };
 426         static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
 427         static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
 428         static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
 429 
 430         mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
 431         udelay(2000);
 432         mt352_write(fe, mt352_reset, sizeof(mt352_reset));
 433         mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
 434         mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
 435         mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
 436         return 0;
 437 }
 438 
 439 static struct mt352_config samsung_tdtc9251dh0_config = {
 440         .demod_address = 0x0f,
 441         .demod_init    = samsung_tdtc9251dh0_demod_init,
 442 };
 443 
 444 static int airstar_dvbt_attach(struct flexcop_device *fc,
 445         struct i2c_adapter *i2c)
 446 {
 447         fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
 448         if (!fc->fe)
 449                 return 0;
 450 
 451         return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
 452                             DVB_PLL_SAMSUNG_TDTC9251DH0);
 453 }
 454 #else
 455 #define airstar_dvbt_attach NULL
 456 #endif
 457 
 458 /* AirStar ATSC 1st generation */
 459 #if FE_SUPPORTED(BCM3510)
 460 static struct bcm3510_config air2pc_atsc_first_gen_config = {
 461         .demod_address    = 0x0f,
 462         .request_firmware = flexcop_fe_request_firmware,
 463 };
 464 
 465 static int airstar_atsc1_attach(struct flexcop_device *fc,
 466         struct i2c_adapter *i2c)
 467 {
 468         fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
 469         return fc->fe != NULL;
 470 }
 471 #else
 472 #define airstar_atsc1_attach NULL
 473 #endif
 474 
 475 /* AirStar ATSC 2nd generation */
 476 #if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
 477 static const struct nxt200x_config samsung_tbmv_config = {
 478         .demod_address = 0x0a,
 479 };
 480 
 481 static int airstar_atsc2_attach(struct flexcop_device *fc,
 482         struct i2c_adapter *i2c)
 483 {
 484         fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
 485         if (!fc->fe)
 486                 return 0;
 487 
 488         return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
 489                             DVB_PLL_SAMSUNG_TBMV);
 490 }
 491 #else
 492 #define airstar_atsc2_attach NULL
 493 #endif
 494 
 495 /* AirStar ATSC 3rd generation */
 496 #if FE_SUPPORTED(LGDT330X)
 497 static struct lgdt330x_config air2pc_atsc_hd5000_config = {
 498         .demod_chip          = LGDT3303,
 499         .serial_mpeg         = 0x04,
 500         .clock_polarity_flip = 1,
 501 };
 502 
 503 static int airstar_atsc3_attach(struct flexcop_device *fc,
 504         struct i2c_adapter *i2c)
 505 {
 506         fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config,
 507                             0x59, i2c);
 508         if (!fc->fe)
 509                 return 0;
 510 
 511         return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
 512                             TUNER_LG_TDVS_H06XF);
 513 }
 514 #else
 515 #define airstar_atsc3_attach NULL
 516 #endif
 517 
 518 /* CableStar2 DVB-C */
 519 #if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
 520 static u8 alps_tdee4_stv0297_inittab[] = {
 521         0x80, 0x01,
 522         0x80, 0x00,
 523         0x81, 0x01,
 524         0x81, 0x00,
 525         0x00, 0x48,
 526         0x01, 0x58,
 527         0x03, 0x00,
 528         0x04, 0x00,
 529         0x07, 0x00,
 530         0x08, 0x00,
 531         0x30, 0xff,
 532         0x31, 0x9d,
 533         0x32, 0xff,
 534         0x33, 0x00,
 535         0x34, 0x29,
 536         0x35, 0x55,
 537         0x36, 0x80,
 538         0x37, 0x6e,
 539         0x38, 0x9c,
 540         0x40, 0x1a,
 541         0x41, 0xfe,
 542         0x42, 0x33,
 543         0x43, 0x00,
 544         0x44, 0xff,
 545         0x45, 0x00,
 546         0x46, 0x00,
 547         0x49, 0x04,
 548         0x4a, 0x51,
 549         0x4b, 0xf8,
 550         0x52, 0x30,
 551         0x53, 0x06,
 552         0x59, 0x06,
 553         0x5a, 0x5e,
 554         0x5b, 0x04,
 555         0x61, 0x49,
 556         0x62, 0x0a,
 557         0x70, 0xff,
 558         0x71, 0x04,
 559         0x72, 0x00,
 560         0x73, 0x00,
 561         0x74, 0x0c,
 562         0x80, 0x20,
 563         0x81, 0x00,
 564         0x82, 0x30,
 565         0x83, 0x00,
 566         0x84, 0x04,
 567         0x85, 0x22,
 568         0x86, 0x08,
 569         0x87, 0x1b,
 570         0x88, 0x00,
 571         0x89, 0x00,
 572         0x90, 0x00,
 573         0x91, 0x04,
 574         0xa0, 0x86,
 575         0xa1, 0x00,
 576         0xa2, 0x00,
 577         0xb0, 0x91,
 578         0xb1, 0x0b,
 579         0xc0, 0x5b,
 580         0xc1, 0x10,
 581         0xc2, 0x12,
 582         0xd0, 0x02,
 583         0xd1, 0x00,
 584         0xd2, 0x00,
 585         0xd3, 0x00,
 586         0xd4, 0x02,
 587         0xd5, 0x00,
 588         0xde, 0x00,
 589         0xdf, 0x01,
 590         0xff, 0xff,
 591 };
 592 
 593 static struct stv0297_config alps_tdee4_stv0297_config = {
 594         .demod_address = 0x1c,
 595         .inittab = alps_tdee4_stv0297_inittab,
 596 };
 597 
 598 static int cablestar2_attach(struct flexcop_device *fc,
 599         struct i2c_adapter *i2c)
 600 {
 601         fc->fc_i2c_adap[0].no_base_addr = 1;
 602         fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
 603         if (!fc->fe)
 604                 goto fail;
 605 
 606         /* This tuner doesn't use the stv0297's I2C gate, but instead the
 607          * tuner is connected to a different flexcop I2C adapter.  */
 608         if (fc->fe->ops.i2c_gate_ctrl)
 609                 fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
 610         fc->fe->ops.i2c_gate_ctrl = NULL;
 611 
 612         if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
 613                         &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
 614                 goto fail;
 615 
 616         return 1;
 617 
 618 fail:
 619         /* Reset for next frontend to try */
 620         fc->fc_i2c_adap[0].no_base_addr = 0;
 621         return 0;
 622 }
 623 #else
 624 #define cablestar2_attach NULL
 625 #endif
 626 
 627 /* SkyStar S2 PCI DVB-S/S2 card based on Conexant cx24120/cx24118 */
 628 #if FE_SUPPORTED(CX24120) && FE_SUPPORTED(ISL6421)
 629 static const struct cx24120_config skystar2_rev3_3_cx24120_config = {
 630         .i2c_addr = 0x55,
 631         .xtal_khz = 10111,
 632         .initial_mpeg_config = { 0xa1, 0x76, 0x07 },
 633         .request_firmware = flexcop_fe_request_firmware,
 634         .i2c_wr_max = 4,
 635 };
 636 
 637 static int skystarS2_rev33_attach(struct flexcop_device *fc,
 638         struct i2c_adapter *i2c)
 639 {
 640         fc->fe = dvb_attach(cx24120_attach,
 641                             &skystar2_rev3_3_cx24120_config, i2c);
 642         if (!fc->fe)
 643                 return 0;
 644 
 645         fc->dev_type = FC_SKYS2_REV33;
 646         fc->fc_i2c_adap[2].no_base_addr = 1;
 647         if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
 648                         0x08, 0, 0, false)) {
 649                 err("ISL6421 could NOT be attached!");
 650                 fc->fc_i2c_adap[2].no_base_addr = 0;
 651                 return 0;
 652         }
 653         info("ISL6421 successfully attached.");
 654 
 655         if (fc->has_32_hw_pid_filter)
 656                 fc->skip_6_hw_pid_filter = 1;
 657 
 658         return 1;
 659 }
 660 #else
 661 #define skystarS2_rev33_attach NULL
 662 #endif
 663 
 664 static struct {
 665         flexcop_device_type_t type;
 666         int (*attach)(struct flexcop_device *, struct i2c_adapter *);
 667 } flexcop_frontends[] = {
 668         { FC_SKY_REV27, skystar2_rev27_attach },
 669         { FC_SKY_REV28, skystar2_rev28_attach },
 670         { FC_SKY_REV26, skystar2_rev26_attach },
 671         { FC_AIR_DVBT, airstar_dvbt_attach },
 672         { FC_AIR_ATSC2, airstar_atsc2_attach },
 673         { FC_AIR_ATSC3, airstar_atsc3_attach },
 674         { FC_AIR_ATSC1, airstar_atsc1_attach },
 675         { FC_CABLE, cablestar2_attach },
 676         { FC_SKY_REV23, skystar2_rev23_attach },
 677         { FC_SKYS2_REV33, skystarS2_rev33_attach },
 678 };
 679 
 680 /* try to figure out the frontend */
 681 int flexcop_frontend_init(struct flexcop_device *fc)
 682 {
 683         int i;
 684         for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
 685                 if (!flexcop_frontends[i].attach)
 686                         continue;
 687                 /* type needs to be set before, because of some workarounds
 688                  * done based on the probed card type */
 689                 fc->dev_type = flexcop_frontends[i].type;
 690                 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
 691                         goto fe_found;
 692                 /* Clean up partially attached frontend */
 693                 if (fc->fe) {
 694                         dvb_frontend_detach(fc->fe);
 695                         fc->fe = NULL;
 696                 }
 697         }
 698         fc->dev_type = FC_UNK;
 699         err("no frontend driver found for this B2C2/FlexCop adapter");
 700         return -ENODEV;
 701 
 702 fe_found:
 703         info("found '%s' .", fc->fe->ops.info.name);
 704         if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
 705                 err("frontend registration failed!");
 706                 dvb_frontend_detach(fc->fe);
 707                 fc->fe = NULL;
 708                 return -EINVAL;
 709         }
 710         fc->init_state |= FC_STATE_FE_INIT;
 711         return 0;
 712 }
 713 
 714 void flexcop_frontend_exit(struct flexcop_device *fc)
 715 {
 716         if (fc->init_state & FC_STATE_FE_INIT) {
 717                 dvb_unregister_frontend(fc->fe);
 718                 dvb_frontend_detach(fc->fe);
 719         }
 720         fc->init_state &= ~FC_STATE_FE_INIT;
 721 }

/* [<][>][^][v][top][bottom][index][help] */