cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ascot2e.c (15066B)


      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
     22enum ascot2e_state {
     23	STATE_UNKNOWN,
     24	STATE_SLEEP,
     25	STATE_ACTIVE
     26};
     27
     28struct 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
     37enum 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
     54struct 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
     74static 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
    103static 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
    112static 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
    147static 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
    154static 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 = &reg,
    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
    194static int ascot2e_read_reg(struct ascot2e_priv *priv, u8 reg, u8 *val)
    195{
    196	return ascot2e_read_regs(priv, reg, val, 1);
    197}
    198
    199static 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
    214static 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
    229static 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
    242static 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
    250static 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
    259static 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
    268static 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
    312static 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
    451static 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
    459static 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
    473struct 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}
    536EXPORT_SYMBOL(ascot2e_attach);
    537
    538MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver");
    539MODULE_AUTHOR("info@netup.ru");
    540MODULE_LICENSE("GPL");