Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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