brintos

brintos / linux-shallow public Read only

0
0
Text · 70.4 KiB · 83cf6ea Raw
2585 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.4 *5 * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)6 */7 8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt9 10#include <linux/kernel.h>11#include <linux/i2c.h>12#include <linux/mutex.h>13 14#include <linux/int_log.h>15#include <media/dvb_frontend.h>16 17#include "dib9000.h"18#include "dibx000_common.h"19 20static int debug;21module_param(debug, int, 0644);22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");23 24#define dprintk(fmt, arg...) do {					\25	if (debug)							\26		printk(KERN_DEBUG pr_fmt("%s: " fmt),			\27		       __func__, ##arg);				\28} while (0)29 30#define MAX_NUMBER_OF_FRONTENDS 631 32struct i2c_device {33	struct i2c_adapter *i2c_adap;34	u8 i2c_addr;35	u8 *i2c_read_buffer;36	u8 *i2c_write_buffer;37};38 39struct dib9000_pid_ctrl {40#define DIB9000_PID_FILTER_CTRL 041#define DIB9000_PID_FILTER      142	u8 cmd;43	u8 id;44	u16 pid;45	u8 onoff;46};47 48struct dib9000_state {49	struct i2c_device i2c;50 51	struct dibx000_i2c_master i2c_master;52	struct i2c_adapter tuner_adap;53	struct i2c_adapter component_bus;54 55	u16 revision;56	u8 reg_offs;57 58	enum frontend_tune_state tune_state;59	u32 status;60	struct dvb_frontend_parametersContext channel_status;61 62	u8 fe_id;63 64#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff65	u16 gpio_dir;66#define DIB9000_GPIO_DEFAULT_VALUES     0x000067	u16 gpio_val;68#define DIB9000_GPIO_DEFAULT_PWM_POS    0xffff69	u16 gpio_pwm_pos;70 71	union {			/* common for all chips */72		struct {73			u8 mobile_mode:1;74		} host;75 76		struct {77			struct dib9000_fe_memory_map {78				u16 addr;79				u16 size;80			} fe_mm[18];81			u8 memcmd;82 83			struct mutex mbx_if_lock;	/* to protect read/write operations */84			struct mutex mbx_lock;	/* to protect the whole mailbox handling */85 86			struct mutex mem_lock;	/* to protect the memory accesses */87			struct mutex mem_mbx_lock;	/* to protect the memory-based mailbox */88 89#define MBX_MAX_WORDS (256 - 200 - 2)90#define DIB9000_MSG_CACHE_SIZE 291			u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];92			u8 fw_is_running;93		} risc;94	} platform;95 96	union {			/* common for all platforms */97		struct {98			struct dib9000_config cfg;99		} d9;100	} chip;101 102	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];103	u16 component_bus_speed;104 105	/* for the I2C transfer */106	struct i2c_msg msg[2];107	u8 i2c_write_buffer[255];108	u8 i2c_read_buffer[255];109	struct mutex demod_lock;110	u8 get_frontend_internal;111	struct dib9000_pid_ctrl pid_ctrl[10];112	s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */113};114 115static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,116	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117	0, 0, 0, 0, 0, 0, 0, 0118};119 120enum dib9000_power_mode {121	DIB9000_POWER_ALL = 0,122 123	DIB9000_POWER_NO,124	DIB9000_POWER_INTERF_ANALOG_AGC,125	DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,126	DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,127	DIB9000_POWER_INTERFACE_ONLY,128};129 130enum dib9000_out_messages {131	OUT_MSG_HBM_ACK,132	OUT_MSG_HOST_BUF_FAIL,133	OUT_MSG_REQ_VERSION,134	OUT_MSG_BRIDGE_I2C_W,135	OUT_MSG_BRIDGE_I2C_R,136	OUT_MSG_BRIDGE_APB_W,137	OUT_MSG_BRIDGE_APB_R,138	OUT_MSG_SCAN_CHANNEL,139	OUT_MSG_MONIT_DEMOD,140	OUT_MSG_CONF_GPIO,141	OUT_MSG_DEBUG_HELP,142	OUT_MSG_SUBBAND_SEL,143	OUT_MSG_ENABLE_TIME_SLICE,144	OUT_MSG_FE_FW_DL,145	OUT_MSG_FE_CHANNEL_SEARCH,146	OUT_MSG_FE_CHANNEL_TUNE,147	OUT_MSG_FE_SLEEP,148	OUT_MSG_FE_SYNC,149	OUT_MSG_CTL_MONIT,150 151	OUT_MSG_CONF_SVC,152	OUT_MSG_SET_HBM,153	OUT_MSG_INIT_DEMOD,154	OUT_MSG_ENABLE_DIVERSITY,155	OUT_MSG_SET_OUTPUT_MODE,156	OUT_MSG_SET_PRIORITARY_CHANNEL,157	OUT_MSG_ACK_FRG,158	OUT_MSG_INIT_PMU,159};160 161enum dib9000_in_messages {162	IN_MSG_DATA,163	IN_MSG_FRAME_INFO,164	IN_MSG_CTL_MONIT,165	IN_MSG_ACK_FREE_ITEM,166	IN_MSG_DEBUG_BUF,167	IN_MSG_MPE_MONITOR,168	IN_MSG_RAWTS_MONITOR,169	IN_MSG_END_BRIDGE_I2C_RW,170	IN_MSG_END_BRIDGE_APB_RW,171	IN_MSG_VERSION,172	IN_MSG_END_OF_SCAN,173	IN_MSG_MONIT_DEMOD,174	IN_MSG_ERROR,175	IN_MSG_FE_FW_DL_DONE,176	IN_MSG_EVENT,177	IN_MSG_ACK_CHANGE_SVC,178	IN_MSG_HBM_PROF,179};180 181/* memory_access requests */182#define FE_MM_W_CHANNEL                   0183#define FE_MM_W_FE_INFO                   1184#define FE_MM_RW_SYNC                     2185 186#define FE_SYNC_CHANNEL          1187#define FE_SYNC_W_GENERIC_MONIT	 2188#define FE_SYNC_COMPONENT_ACCESS 3189 190#define FE_MM_R_CHANNEL_SEARCH_STATE      3191#define FE_MM_R_CHANNEL_UNION_CONTEXT     4192#define FE_MM_R_FE_INFO                   5193#define FE_MM_R_FE_MONITOR                6194 195#define FE_MM_W_CHANNEL_HEAD              7196#define FE_MM_W_CHANNEL_UNION             8197#define FE_MM_W_CHANNEL_CONTEXT           9198#define FE_MM_R_CHANNEL_UNION            10199#define FE_MM_R_CHANNEL_CONTEXT          11200#define FE_MM_R_CHANNEL_TUNE_STATE       12201 202#define FE_MM_R_GENERIC_MONITORING_SIZE	 13203#define FE_MM_W_GENERIC_MONITORING	     14204#define FE_MM_R_GENERIC_MONITORING	     15205 206#define FE_MM_W_COMPONENT_ACCESS         16207#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17208static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);209static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);210 211static u16 to_fw_output_mode(u16 mode)212{213	switch (mode) {214	case OUTMODE_HIGH_Z:215		return 0;216	case OUTMODE_MPEG2_PAR_GATED_CLK:217		return 4;218	case OUTMODE_MPEG2_PAR_CONT_CLK:219		return 8;220	case OUTMODE_MPEG2_SERIAL:221		return 16;222	case OUTMODE_DIVERSITY:223		return 128;224	case OUTMODE_MPEG2_FIFO:225		return 2;226	case OUTMODE_ANALOG_ADC:227		return 1;228	default:229		return 0;230	}231}232 233static int dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 *b, u32 len, u16 attribute)234{235	u32 chunk_size = 126;236	u32 l;237	int ret;238 239	if (state->platform.risc.fw_is_running && (reg < 1024))240		return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);241 242	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));243	state->msg[0].addr = state->i2c.i2c_addr >> 1;244	state->msg[0].flags = 0;245	state->msg[0].buf = state->i2c_write_buffer;246	state->msg[0].len = 2;247	state->msg[1].addr = state->i2c.i2c_addr >> 1;248	state->msg[1].flags = I2C_M_RD;249	state->msg[1].buf = b;250	state->msg[1].len = len;251 252	state->i2c_write_buffer[0] = reg >> 8;253	state->i2c_write_buffer[1] = reg & 0xff;254 255	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)256		state->i2c_write_buffer[0] |= (1 << 5);257	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)258		state->i2c_write_buffer[0] |= (1 << 4);259 260	do {261		l = min(len, chunk_size);262		state->msg[1].len = l;263		state->msg[1].buf = b;264		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;265		if (ret != 0) {266			dprintk("i2c read error on %d\n", reg);267			return -EREMOTEIO;268		}269 270		b += l;271		len -= l;272 273		if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))274			reg += l / 2;275	} while ((ret == 0) && len);276 277	return 0;278}279 280static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)281{282	struct i2c_msg msg[2] = {283		{.addr = i2c->i2c_addr >> 1, .flags = 0,284			.buf = i2c->i2c_write_buffer, .len = 2},285		{.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,286			.buf = i2c->i2c_read_buffer, .len = 2},287	};288 289	i2c->i2c_write_buffer[0] = reg >> 8;290	i2c->i2c_write_buffer[1] = reg & 0xff;291 292	if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {293		dprintk("read register %x error\n", reg);294		return 0;295	}296 297	return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];298}299 300static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)301{302	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)303		return 0;304	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];305}306 307static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)308{309	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,310				attribute) != 0)311		return 0;312	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];313}314 315#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)316 317static int dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *buf, u32 len, u16 attribute)318{319	u32 chunk_size = 126;320	u32 l;321	int ret;322 323	if (state->platform.risc.fw_is_running && (reg < 1024)) {324		if (dib9000_risc_apb_access_write325		    (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)326			return -EINVAL;327		return 0;328	}329 330	memset(&state->msg[0], 0, sizeof(struct i2c_msg));331	state->msg[0].addr = state->i2c.i2c_addr >> 1;332	state->msg[0].flags = 0;333	state->msg[0].buf = state->i2c_write_buffer;334	state->msg[0].len = len + 2;335 336	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;337	state->i2c_write_buffer[1] = (reg) & 0xff;338 339	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)340		state->i2c_write_buffer[0] |= (1 << 5);341	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)342		state->i2c_write_buffer[0] |= (1 << 4);343 344	do {345		l = min(len, chunk_size);346		state->msg[0].len = l + 2;347		memcpy(&state->i2c_write_buffer[2], buf, l);348 349		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;350 351		buf += l;352		len -= l;353 354		if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))355			reg += l / 2;356	} while ((ret == 0) && len);357 358	return ret;359}360 361static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)362{363	struct i2c_msg msg = {364		.addr = i2c->i2c_addr >> 1, .flags = 0,365		.buf = i2c->i2c_write_buffer, .len = 4366	};367 368	i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;369	i2c->i2c_write_buffer[1] = reg & 0xff;370	i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;371	i2c->i2c_write_buffer[3] = val & 0xff;372 373	return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;374}375 376static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)377{378	u8 b[2] = { val >> 8, val & 0xff };379	return dib9000_write16_attr(state, reg, b, 2, 0);380}381 382static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)383{384	u8 b[2] = { val >> 8, val & 0xff };385	return dib9000_write16_attr(state, reg, b, 2, attribute);386}387 388#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)389#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)390#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))391 392#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)393#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)394 395#define MAC_IRQ      (1 << 1)396#define IRQ_POL_MSK  (1 << 4)397 398#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)399#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)400 401static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)402{403	u8 b[14] = { 0 };404 405/*      dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */406/*      b[0] = 0 << 7; */407	b[1] = 1;408 409/*      b[2] = 0; */410/*      b[3] = 0; */411	b[4] = (u8) (addr >> 8);412	b[5] = (u8) (addr & 0xff);413 414/*      b[10] = 0; */415/*      b[11] = 0; */416	b[12] = (u8) (addr >> 8);417	b[13] = (u8) (addr & 0xff);418 419	addr += len;420/*      b[6] = 0; */421/*      b[7] = 0; */422	b[8] = (u8) (addr >> 8);423	b[9] = (u8) (addr & 0xff);424 425	dib9000_write(state, 1056, b, 14);426	if (reading)427		dib9000_write_word(state, 1056, (1 << 15) | 1);428	state->platform.risc.memcmd = -1;	/* if it was called directly reset it - to force a future setup-call to set it */429}430 431static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)432{433	struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];434	/* decide whether we need to "refresh" the memory controller */435	if (state->platform.risc.memcmd == cmd &&	/* same command */436	    !(cmd & 0x80 && m->size < 67))	/* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */437		return;438	dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);439	state->platform.risc.memcmd = cmd;440}441 442static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)443{444	if (!state->platform.risc.fw_is_running)445		return -EIO;446 447	if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {448		dprintk("could not get the lock\n");449		return -EINTR;450	}451	dib9000_risc_mem_setup(state, cmd | 0x80);452	dib9000_risc_mem_read_chunks(state, b, len);453	mutex_unlock(&state->platform.risc.mem_lock);454	return 0;455}456 457static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)458{459	struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];460	if (!state->platform.risc.fw_is_running)461		return -EIO;462 463	if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {464		dprintk("could not get the lock\n");465		return -EINTR;466	}467	dib9000_risc_mem_setup(state, cmd);468	dib9000_risc_mem_write_chunks(state, b, m->size);469	mutex_unlock(&state->platform.risc.mem_lock);470	return 0;471}472 473static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)474{475	u16 offs;476 477	if (risc_id == 1)478		offs = 16;479	else480		offs = 0;481 482	/* config crtl reg */483	dib9000_write_word(state, 1024 + offs, 0x000f);484	dib9000_write_word(state, 1025 + offs, 0);485	dib9000_write_word(state, 1031 + offs, key);486 487	dprintk("going to download %dB of microcode\n", len);488	if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {489		dprintk("error while downloading microcode for RISC %c\n", 'A' + risc_id);490		return -EIO;491	}492 493	dprintk("Microcode for RISC %c loaded\n", 'A' + risc_id);494 495	return 0;496}497 498static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)499{500	u16 mbox_offs;501	u16 reset_reg;502	u16 tries = 1000;503 504	if (risc_id == 1)505		mbox_offs = 16;506	else507		mbox_offs = 0;508 509	/* Reset mailbox  */510	dib9000_write_word(state, 1027 + mbox_offs, 0x8000);511 512	/* Read reset status */513	do {514		reset_reg = dib9000_read_word(state, 1027 + mbox_offs);515		msleep(100);516	} while ((reset_reg & 0x8000) && --tries);517 518	if (reset_reg & 0x8000) {519		dprintk("MBX: init ERROR, no response from RISC %c\n", 'A' + risc_id);520		return -EIO;521	}522	dprintk("MBX: initialized\n");523	return 0;524}525 526#define MAX_MAILBOX_TRY 100527static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)528{529	u8 *d, b[2];530	u16 tmp;531	u16 size;532	u32 i;533	int ret = 0;534 535	if (!state->platform.risc.fw_is_running)536		return -EINVAL;537 538	if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {539		dprintk("could not get the lock\n");540		return -EINTR;541	}542	tmp = MAX_MAILBOX_TRY;543	do {544		size = dib9000_read_word_attr(state, 1043, attr) & 0xff;545		if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {546			dprintk("MBX: RISC mbx full, retrying\n");547			msleep(100);548		} else549			break;550	} while (1);551 552	/*dprintk( "MBX: size: %d\n", size); */553 554	if (tmp == 0) {555		ret = -EINVAL;556		goto out;557	}558#ifdef DUMP_MSG559	dprintk("--> %02x %d %*ph\n", id, len + 1, len, data);560#endif561 562	/* byte-order conversion - works on big (where it is not necessary) or little endian */563	d = (u8 *) data;564	for (i = 0; i < len; i++) {565		tmp = data[i];566		*d++ = tmp >> 8;567		*d++ = tmp & 0xff;568	}569 570	/* write msg */571	b[0] = id;572	b[1] = len + 1;573	if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {574		ret = -EIO;575		goto out;576	}577 578	/* update register nb_mes_in_RX */579	ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);580 581out:582	mutex_unlock(&state->platform.risc.mbx_if_lock);583 584	return ret;585}586 587static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)588{589#ifdef DUMP_MSG590	u16 *d = data;591#endif592 593	u16 tmp, i;594	u8 size;595	u8 mc_base;596 597	if (!state->platform.risc.fw_is_running)598		return 0;599 600	if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {601		dprintk("could not get the lock\n");602		return 0;603	}604	if (risc_id == 1)605		mc_base = 16;606	else607		mc_base = 0;608 609	/* Length and type in the first word */610	*data = dib9000_read_word_attr(state, 1029 + mc_base, attr);611 612	size = *data & 0xff;613	if (size <= MBX_MAX_WORDS) {614		data++;615		size--;		/* Initial word already read */616 617		dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);618 619		/* to word conversion */620		for (i = 0; i < size; i++) {621			tmp = *data;622			*data = (tmp >> 8) | (tmp << 8);623			data++;624		}625 626#ifdef DUMP_MSG627		dprintk("<--\n");628		for (i = 0; i < size + 1; i++)629			dprintk("%04x\n", d[i]);630		dprintk("\n");631#endif632	} else {633		dprintk("MBX: message is too big for message cache (%d), flushing message\n", size);634		size--;		/* Initial word already read */635		while (size--)636			dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);637	}638	/* Update register nb_mes_in_TX */639	dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);640 641	mutex_unlock(&state->platform.risc.mbx_if_lock);642 643	return size + 1;644}645 646static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)647{648	u32 ts = data[1] << 16 | data[0];649	char *b = (char *)&data[2];650 651	b[2 * (size - 2) - 1] = '\0';	/* Bullet proof the buffer */652	if (*b == '~') {653		b++;654		dprintk("%s\n", b);655	} else656		dprintk("RISC%d: %d.%04d %s\n",657			state->fe_id,658			ts / 10000, ts % 10000, *b ? b : "<empty>");659	return 1;660}661 662static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)663{664	int i;665	u8 size;666	u16 *block;667	/* find a free slot */668	for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {669		block = state->platform.risc.message_cache[i];670		if (*block == 0) {671			size = dib9000_mbx_read(state, block, 1, attr);672 673/*                      dprintk( "MBX: fetched %04x message to cache\n", *block); */674 675			switch (*block >> 8) {676			case IN_MSG_DEBUG_BUF:677				dib9000_risc_debug_buf(state, block + 1, size);	/* debug-messages are going to be printed right away */678				*block = 0;	/* free the block */679				break;680#if 0681			case IN_MSG_DATA:	/* FE-TRACE */682				dib9000_risc_data_process(state, block + 1, size);683				*block = 0;684				break;685#endif686			default:687				break;688			}689 690			return 1;691		}692	}693	dprintk("MBX: no free cache-slot found for new message...\n");694	return -1;695}696 697static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)698{699	if (risc_id == 0)700		return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f;	/* 5 bit field */701	else702		return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f;	/* 7 bit field */703}704 705static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)706{707	int ret = 0;708 709	if (!state->platform.risc.fw_is_running)710		return -1;711 712	if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {713		dprintk("could not get the lock\n");714		return -1;715	}716 717	if (dib9000_mbx_count(state, 1, attr))	/* 1=RiscB */718		ret = dib9000_mbx_fetch_to_cache(state, attr);719 720	dib9000_read_word_attr(state, 1229, attr);	/* Clear the IRQ */721/*      if (tmp) */722/*              dprintk( "cleared IRQ: %x\n", tmp); */723	mutex_unlock(&state->platform.risc.mbx_lock);724 725	return ret;726}727 728static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)729{730	u8 i;731	u16 *block;732	u16 timeout = 30;733 734	*msg = 0;735	do {736		/* dib9000_mbx_get_from_cache(); */737		for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {738			block = state->platform.risc.message_cache[i];739			if ((*block >> 8) == id) {740				*size = (*block & 0xff) - 1;741				memcpy(msg, block + 1, (*size) * 2);742				*block = 0;	/* free the block */743				i = 0;	/* signal that we found a message */744				break;745			}746		}747 748		if (i == 0)749			break;750 751		if (dib9000_mbx_process(state, attr) == -1)	/* try to fetch one message - if any */752			return -1;753 754	} while (--timeout);755 756	if (timeout == 0) {757		dprintk("waiting for message %d timed out\n", id);758		return -1;759	}760 761	return i == 0;762}763 764static int dib9000_risc_check_version(struct dib9000_state *state)765{766	u8 r[4];767	u8 size;768	u16 fw_version = 0;769 770	if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)771		return -EIO;772 773	if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)774		return -EIO;775 776	fw_version = (r[0] << 8) | r[1];777	dprintk("RISC: ver: %d.%02d (IC: %d)\n", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);778 779	if ((fw_version >> 10) != 7)780		return -EINVAL;781 782	switch (fw_version & 0x3ff) {783	case 11:784	case 12:785	case 14:786	case 15:787	case 16:788	case 17:789		break;790	default:791		dprintk("RISC: invalid firmware version");792		return -EINVAL;793	}794 795	dprintk("RISC: valid firmware version");796	return 0;797}798 799static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)800{801	/* Reconfig pool mac ram */802	dib9000_write_word(state, 1225, 0x02);	/* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */803	dib9000_write_word(state, 1226, 0x05);804 805	/* Toggles IP crypto to Host APB interface. */806	dib9000_write_word(state, 1542, 1);807 808	/* Set jump and no jump in the dma box */809	dib9000_write_word(state, 1074, 0);810	dib9000_write_word(state, 1075, 0);811 812	/* Set MAC as APB Master. */813	dib9000_write_word(state, 1237, 0);814 815	/* Reset the RISCs */816	if (codeA != NULL)817		dib9000_write_word(state, 1024, 2);818	else819		dib9000_write_word(state, 1024, 15);820	if (codeB != NULL)821		dib9000_write_word(state, 1040, 2);822 823	if (codeA != NULL)824		dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);825	if (codeB != NULL)826		dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);827 828	/* Run the RISCs */829	if (codeA != NULL)830		dib9000_write_word(state, 1024, 0);831	if (codeB != NULL)832		dib9000_write_word(state, 1040, 0);833 834	if (codeA != NULL)835		if (dib9000_mbx_host_init(state, 0) != 0)836			return -EIO;837	if (codeB != NULL)838		if (dib9000_mbx_host_init(state, 1) != 0)839			return -EIO;840 841	msleep(100);842	state->platform.risc.fw_is_running = 1;843 844	if (dib9000_risc_check_version(state) != 0)845		return -EINVAL;846 847	state->platform.risc.memcmd = 0xff;848	return 0;849}850 851static u16 dib9000_identify(struct i2c_device *client)852{853	u16 value;854 855	value = dib9000_i2c_read16(client, 896);856	if (value != 0x01b3) {857		dprintk("wrong Vendor ID (0x%x)\n", value);858		return 0;859	}860 861	value = dib9000_i2c_read16(client, 897);862	if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {863		dprintk("wrong Device ID (0x%x)\n", value);864		return 0;865	}866 867	/* protect this driver to be used with 7000PC */868	if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {869		dprintk("this driver does not work with DiB7000PC\n");870		return 0;871	}872 873	switch (value) {874	case 0x4000:875		dprintk("found DiB7000MA/PA/MB/PB\n");876		break;877	case 0x4001:878		dprintk("found DiB7000HC\n");879		break;880	case 0x4002:881		dprintk("found DiB7000MC\n");882		break;883	case 0x4003:884		dprintk("found DiB9000A\n");885		break;886	case 0x4004:887		dprintk("found DiB9000H\n");888		break;889	case 0x4005:890		dprintk("found DiB9000M\n");891		break;892	}893 894	return value;895}896 897static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)898{899	/* by default everything is going to be powered off */900	u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;901	u8 offset;902 903	if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)904		offset = 1;905	else906		offset = 0;907 908	reg_906 = dib9000_read_word(state, 906 + offset) | 0x3;	/* keep settings for RISC */909 910	/* now, depending on the requested mode, we power on */911	switch (mode) {912		/* power up everything in the demod */913	case DIB9000_POWER_ALL:914		reg_903 = 0x0000;915		reg_904 = 0x0000;916		reg_905 = 0x0000;917		reg_906 = 0x0000;918		break;919 920		/* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */921	case DIB9000_POWER_INTERFACE_ONLY:	/* TODO power up either SDIO or I2C or SRAM */922		reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));923		break;924 925	case DIB9000_POWER_INTERF_ANALOG_AGC:926		reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));927		reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));928		reg_906 &= ~((1 << 0));929		break;930 931	case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:932		reg_903 = 0x0000;933		reg_904 = 0x801f;934		reg_905 = 0x0000;935		reg_906 &= ~((1 << 0));936		break;937 938	case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:939		reg_903 = 0x0000;940		reg_904 = 0x8000;941		reg_905 = 0x010b;942		reg_906 &= ~((1 << 0));943		break;944	default:945	case DIB9000_POWER_NO:946		break;947	}948 949	/* always power down unused parts */950	if (!state->platform.host.mobile_mode)951		reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);952 953	/* P_sdio_select_clk = 0 on MC and after */954	if (state->revision != 0x4000)955		reg_906 <<= 1;956 957	dib9000_write_word(state, 903 + offset, reg_903);958	dib9000_write_word(state, 904 + offset, reg_904);959	dib9000_write_word(state, 905 + offset, reg_905);960	dib9000_write_word(state, 906 + offset, reg_906);961}962 963static int dib9000_fw_reset(struct dvb_frontend *fe)964{965	struct dib9000_state *state = fe->demodulator_priv;966 967	dib9000_write_word(state, 1817, 0x0003);968 969	dib9000_write_word(state, 1227, 1);970	dib9000_write_word(state, 1227, 0);971 972	switch ((state->revision = dib9000_identify(&state->i2c))) {973	case 0x4003:974	case 0x4004:975	case 0x4005:976		state->reg_offs = 1;977		break;978	default:979		return -EINVAL;980	}981 982	/* reset the i2c-master to use the host interface */983	dibx000_reset_i2c_master(&state->i2c_master);984 985	dib9000_set_power_mode(state, DIB9000_POWER_ALL);986 987	/* unforce divstr regardless whether i2c enumeration was done or not */988	dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));989	dib9000_write_word(state, 1796, 0);990	dib9000_write_word(state, 1805, 0x805);991 992	/* restart all parts */993	dib9000_write_word(state, 898, 0xffff);994	dib9000_write_word(state, 899, 0xffff);995	dib9000_write_word(state, 900, 0x0001);996	dib9000_write_word(state, 901, 0xff19);997	dib9000_write_word(state, 902, 0x003c);998 999	dib9000_write_word(state, 898, 0);1000	dib9000_write_word(state, 899, 0);1001	dib9000_write_word(state, 900, 0);1002	dib9000_write_word(state, 901, 0);1003	dib9000_write_word(state, 902, 0);1004 1005	dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);1006 1007	dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);1008 1009	return 0;1010}1011 1012static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)1013{1014	u16 mb[10];1015	u8 i, s;1016 1017	if (address >= 1024 || !state->platform.risc.fw_is_running)1018		return -EINVAL;1019 1020	/* dprintk( "APB access through rd fw %d %x\n", address, attribute); */1021 1022	mb[0] = (u16) address;1023	mb[1] = len / 2;1024	dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);1025	switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {1026	case 1:1027		s--;1028		for (i = 0; i < s; i++) {1029			b[i * 2] = (mb[i + 1] >> 8) & 0xff;1030			b[i * 2 + 1] = (mb[i + 1]) & 0xff;1031		}1032		return 0;1033	default:1034		return -EIO;1035	}1036	return -EIO;1037}1038 1039static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)1040{1041	u16 mb[10];1042	u8 s, i;1043 1044	if (address >= 1024 || !state->platform.risc.fw_is_running)1045		return -EINVAL;1046 1047	if (len > 18)1048		return -EINVAL;1049 1050	/* dprintk( "APB access through wr fw %d %x\n", address, attribute); */1051 1052	mb[0] = (u16)address;1053	for (i = 0; i + 1 < len; i += 2)1054		mb[1 + i / 2] = b[i] << 8 | b[i + 1];1055	if (len & 1)1056		mb[1 + len / 2] = b[len - 1] << 8;1057 1058	dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);1059	return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;1060}1061 1062static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)1063{1064	u8 index_loop = 10;1065 1066	if (!state->platform.risc.fw_is_running)1067		return 0;1068	dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);1069	do {1070		dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);1071	} while (state->i2c_read_buffer[0] && index_loop--);1072 1073	if (index_loop > 0)1074		return 0;1075	return -EIO;1076}1077 1078static int dib9000_fw_init(struct dib9000_state *state)1079{1080	struct dibGPIOFunction *f;1081	u16 b[40] = { 0 };1082	u8 i;1083	u8 size;1084 1085	if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)1086		return -EIO;1087 1088	/* initialize the firmware */1089	for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {1090		f = &state->chip.d9.cfg.gpio_function[i];1091		if (f->mask) {1092			switch (f->function) {1093			case BOARD_GPIO_FUNCTION_COMPONENT_ON:1094				b[0] = (u16) f->mask;1095				b[1] = (u16) f->direction;1096				b[2] = (u16) f->value;1097				break;1098			case BOARD_GPIO_FUNCTION_COMPONENT_OFF:1099				b[3] = (u16) f->mask;1100				b[4] = (u16) f->direction;1101				b[5] = (u16) f->value;1102				break;1103			}1104		}1105	}1106	if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)1107		return -EIO;1108 1109	/* subband */1110	b[0] = state->chip.d9.cfg.subband.size;	/* type == 0 -> GPIO - PWM not yet supported */1111	for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {1112		b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;1113		b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;1114		b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;1115		b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;1116	}1117	b[1 + i * 4] = 0;	/* fe_id */1118	if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)1119		return -EIO;1120 1121	/* 0 - id, 1 - no_of_frontends */1122	b[0] = (0 << 8) | 1;1123	/* 0 = i2c-address demod, 0 = tuner */1124	b[1] = (0 << 8) | (0);1125	b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);1126	b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);1127	b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);1128	b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);1129	b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);1130	b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);1131	b[29] = state->chip.d9.cfg.if_drives;1132	if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)1133		return -EIO;1134 1135	if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)1136		return -EIO;1137 1138	if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)1139		return -EIO;1140 1141	if (size > ARRAY_SIZE(b)) {1142		dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,1143			(int)ARRAY_SIZE(b));1144		return -EINVAL;1145	}1146 1147	for (i = 0; i < size; i += 2) {1148		state->platform.risc.fe_mm[i / 2].addr = b[i + 0];1149		state->platform.risc.fe_mm[i / 2].size = b[i + 1];1150	}1151 1152	return 0;1153}1154 1155static void dib9000_fw_set_channel_head(struct dib9000_state *state)1156{1157	u8 b[9];1158	u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;1159	if (state->fe_id % 2)1160		freq += 101;1161 1162	b[0] = (u8) ((freq >> 0) & 0xff);1163	b[1] = (u8) ((freq >> 8) & 0xff);1164	b[2] = (u8) ((freq >> 16) & 0xff);1165	b[3] = (u8) ((freq >> 24) & 0xff);1166	b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);1167	b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);1168	b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);1169	b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);1170	b[8] = 0x80;		/* do not wait for CELL ID when doing autosearch */1171	if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)1172		b[8] |= 1;1173	dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);1174}1175 1176static int dib9000_fw_get_channel(struct dvb_frontend *fe)1177{1178	struct dib9000_state *state = fe->demodulator_priv;1179	struct dibDVBTChannel {1180		s8 spectrum_inversion;1181 1182		s8 nfft;1183		s8 guard;1184		s8 constellation;1185 1186		s8 hrch;1187		s8 alpha;1188		s8 code_rate_hp;1189		s8 code_rate_lp;1190		s8 select_hp;1191 1192		s8 intlv_native;1193	};1194	struct dibDVBTChannel *ch;1195	int ret = 0;1196 1197	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {1198		dprintk("could not get the lock\n");1199		return -EINTR;1200	}1201	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {1202		ret = -EIO;1203		goto error;1204	}1205 1206	dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,1207			state->i2c_read_buffer, sizeof(struct dibDVBTChannel));1208	ch = (struct dibDVBTChannel *)state->i2c_read_buffer;1209 1210 1211	switch (ch->spectrum_inversion & 0x7) {1212	case 1:1213		state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;1214		break;1215	case 0:1216		state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;1217		break;1218	default:1219	case -1:1220		state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;1221		break;1222	}1223	switch (ch->nfft) {1224	case 0:1225		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;1226		break;1227	case 2:1228		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;1229		break;1230	case 1:1231		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;1232		break;1233	default:1234	case -1:1235		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;1236		break;1237	}1238	switch (ch->guard) {1239	case 0:1240		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;1241		break;1242	case 1:1243		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;1244		break;1245	case 2:1246		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;1247		break;1248	case 3:1249		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;1250		break;1251	default:1252	case -1:1253		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;1254		break;1255	}1256	switch (ch->constellation) {1257	case 2:1258		state->fe[0]->dtv_property_cache.modulation = QAM_64;1259		break;1260	case 1:1261		state->fe[0]->dtv_property_cache.modulation = QAM_16;1262		break;1263	case 0:1264		state->fe[0]->dtv_property_cache.modulation = QPSK;1265		break;1266	default:1267	case -1:1268		state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;1269		break;1270	}1271	switch (ch->hrch) {1272	case 0:1273		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;1274		break;1275	case 1:1276		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;1277		break;1278	default:1279	case -1:1280		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;1281		break;1282	}1283	switch (ch->code_rate_hp) {1284	case 1:1285		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;1286		break;1287	case 2:1288		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;1289		break;1290	case 3:1291		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;1292		break;1293	case 5:1294		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;1295		break;1296	case 7:1297		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;1298		break;1299	default:1300	case -1:1301		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;1302		break;1303	}1304	switch (ch->code_rate_lp) {1305	case 1:1306		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;1307		break;1308	case 2:1309		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;1310		break;1311	case 3:1312		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;1313		break;1314	case 5:1315		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;1316		break;1317	case 7:1318		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;1319		break;1320	default:1321	case -1:1322		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;1323		break;1324	}1325 1326error:1327	mutex_unlock(&state->platform.risc.mem_mbx_lock);1328	return ret;1329}1330 1331static int dib9000_fw_set_channel_union(struct dvb_frontend *fe)1332{1333	struct dib9000_state *state = fe->demodulator_priv;1334	struct dibDVBTChannel {1335		s8 spectrum_inversion;1336 1337		s8 nfft;1338		s8 guard;1339		s8 constellation;1340 1341		s8 hrch;1342		s8 alpha;1343		s8 code_rate_hp;1344		s8 code_rate_lp;1345		s8 select_hp;1346 1347		s8 intlv_native;1348	};1349	struct dibDVBTChannel ch;1350 1351	switch (state->fe[0]->dtv_property_cache.inversion) {1352	case INVERSION_ON:1353		ch.spectrum_inversion = 1;1354		break;1355	case INVERSION_OFF:1356		ch.spectrum_inversion = 0;1357		break;1358	default:1359	case INVERSION_AUTO:1360		ch.spectrum_inversion = -1;1361		break;1362	}1363	switch (state->fe[0]->dtv_property_cache.transmission_mode) {1364	case TRANSMISSION_MODE_2K:1365		ch.nfft = 0;1366		break;1367	case TRANSMISSION_MODE_4K:1368		ch.nfft = 2;1369		break;1370	case TRANSMISSION_MODE_8K:1371		ch.nfft = 1;1372		break;1373	default:1374	case TRANSMISSION_MODE_AUTO:1375		ch.nfft = 1;1376		break;1377	}1378	switch (state->fe[0]->dtv_property_cache.guard_interval) {1379	case GUARD_INTERVAL_1_32:1380		ch.guard = 0;1381		break;1382	case GUARD_INTERVAL_1_16:1383		ch.guard = 1;1384		break;1385	case GUARD_INTERVAL_1_8:1386		ch.guard = 2;1387		break;1388	case GUARD_INTERVAL_1_4:1389		ch.guard = 3;1390		break;1391	default:1392	case GUARD_INTERVAL_AUTO:1393		ch.guard = -1;1394		break;1395	}1396	switch (state->fe[0]->dtv_property_cache.modulation) {1397	case QAM_64:1398		ch.constellation = 2;1399		break;1400	case QAM_16:1401		ch.constellation = 1;1402		break;1403	case QPSK:1404		ch.constellation = 0;1405		break;1406	default:1407	case QAM_AUTO:1408		ch.constellation = -1;1409		break;1410	}1411	switch (state->fe[0]->dtv_property_cache.hierarchy) {1412	case HIERARCHY_NONE:1413		ch.hrch = 0;1414		break;1415	case HIERARCHY_1:1416	case HIERARCHY_2:1417	case HIERARCHY_4:1418		ch.hrch = 1;1419		break;1420	default:1421	case HIERARCHY_AUTO:1422		ch.hrch = -1;1423		break;1424	}1425	ch.alpha = 1;1426	switch (state->fe[0]->dtv_property_cache.code_rate_HP) {1427	case FEC_1_2:1428		ch.code_rate_hp = 1;1429		break;1430	case FEC_2_3:1431		ch.code_rate_hp = 2;1432		break;1433	case FEC_3_4:1434		ch.code_rate_hp = 3;1435		break;1436	case FEC_5_6:1437		ch.code_rate_hp = 5;1438		break;1439	case FEC_7_8:1440		ch.code_rate_hp = 7;1441		break;1442	default:1443	case FEC_AUTO:1444		ch.code_rate_hp = -1;1445		break;1446	}1447	switch (state->fe[0]->dtv_property_cache.code_rate_LP) {1448	case FEC_1_2:1449		ch.code_rate_lp = 1;1450		break;1451	case FEC_2_3:1452		ch.code_rate_lp = 2;1453		break;1454	case FEC_3_4:1455		ch.code_rate_lp = 3;1456		break;1457	case FEC_5_6:1458		ch.code_rate_lp = 5;1459		break;1460	case FEC_7_8:1461		ch.code_rate_lp = 7;1462		break;1463	default:1464	case FEC_AUTO:1465		ch.code_rate_lp = -1;1466		break;1467	}1468	ch.select_hp = 1;1469	ch.intlv_native = 1;1470 1471	dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);1472 1473	return 0;1474}1475 1476static int dib9000_fw_tune(struct dvb_frontend *fe)1477{1478	struct dib9000_state *state = fe->demodulator_priv;1479	int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;1480	s8 i;1481 1482	switch (state->tune_state) {1483	case CT_DEMOD_START:1484		dib9000_fw_set_channel_head(state);1485 1486		/* write the channel context - a channel is initialized to 0, so it is OK */1487		dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);1488		dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);1489 1490		if (search)1491			dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);1492		else {1493			dib9000_fw_set_channel_union(fe);1494			dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);1495		}1496		state->tune_state = CT_DEMOD_STEP_1;1497		break;1498	case CT_DEMOD_STEP_1:1499		if (search)1500			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);1501		else1502			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);1503		i = (s8)state->i2c_read_buffer[0];1504		switch (i) {	/* something happened */1505		case 0:1506			break;1507		case -2:	/* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */1508			if (search)1509				state->status = FE_STATUS_DEMOD_SUCCESS;1510			else {1511				state->tune_state = CT_DEMOD_STOP;1512				state->status = FE_STATUS_LOCKED;1513			}1514			break;1515		default:1516			state->status = FE_STATUS_TUNE_FAILED;1517			state->tune_state = CT_DEMOD_STOP;1518			break;1519		}1520		break;1521	default:1522		ret = FE_CALLBACK_TIME_NEVER;1523		break;1524	}1525 1526	return ret;1527}1528 1529static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)1530{1531	struct dib9000_state *state = fe->demodulator_priv;1532	u16 mode = (u16) onoff;1533	return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);1534}1535 1536static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)1537{1538	struct dib9000_state *state = fe->demodulator_priv;1539	u16 outreg, smo_mode;1540 1541	dprintk("setting output mode for demod %p to %d\n", fe, mode);1542 1543	switch (mode) {1544	case OUTMODE_MPEG2_PAR_GATED_CLK:1545		outreg = (1 << 10);	/* 0x0400 */1546		break;1547	case OUTMODE_MPEG2_PAR_CONT_CLK:1548		outreg = (1 << 10) | (1 << 6);	/* 0x0440 */1549		break;1550	case OUTMODE_MPEG2_SERIAL:1551		outreg = (1 << 10) | (2 << 6) | (0 << 1);	/* 0x0482 */1552		break;1553	case OUTMODE_DIVERSITY:1554		outreg = (1 << 10) | (4 << 6);	/* 0x0500 */1555		break;1556	case OUTMODE_MPEG2_FIFO:1557		outreg = (1 << 10) | (5 << 6);1558		break;1559	case OUTMODE_HIGH_Z:1560		outreg = 0;1561		break;1562	default:1563		dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->fe[0]);1564		return -EINVAL;1565	}1566 1567	dib9000_write_word(state, 1795, outreg);1568 1569	switch (mode) {1570	case OUTMODE_MPEG2_PAR_GATED_CLK:1571	case OUTMODE_MPEG2_PAR_CONT_CLK:1572	case OUTMODE_MPEG2_SERIAL:1573	case OUTMODE_MPEG2_FIFO:1574		smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);1575		if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)1576			smo_mode |= (1 << 5);1577		dib9000_write_word(state, 295, smo_mode);1578		break;1579	}1580 1581	outreg = to_fw_output_mode(mode);1582	return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);1583}1584 1585static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)1586{1587	struct dib9000_state *state = i2c_get_adapdata(i2c_adap);1588	u16 i, len, t, index_msg;1589 1590	for (index_msg = 0; index_msg < num; index_msg++) {1591		if (msg[index_msg].flags & I2C_M_RD) {	/* read */1592			len = msg[index_msg].len;1593			if (len > 16)1594				len = 16;1595 1596			if (dib9000_read_word(state, 790) != 0)1597				dprintk("TunerITF: read busy\n");1598 1599			dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));1600			dib9000_write_word(state, 787, (len / 2) - 1);1601			dib9000_write_word(state, 786, 1);	/* start read */1602 1603			i = 1000;1604			while (dib9000_read_word(state, 790) != (len / 2) && i)1605				i--;1606 1607			if (i == 0)1608				dprintk("TunerITF: read failed\n");1609 1610			for (i = 0; i < len; i += 2) {1611				t = dib9000_read_word(state, 785);1612				msg[index_msg].buf[i] = (t >> 8) & 0xff;1613				msg[index_msg].buf[i + 1] = (t) & 0xff;1614			}1615			if (dib9000_read_word(state, 790) != 0)1616				dprintk("TunerITF: read more data than expected\n");1617		} else {1618			i = 1000;1619			while (dib9000_read_word(state, 789) && i)1620				i--;1621			if (i == 0)1622				dprintk("TunerITF: write busy\n");1623 1624			len = msg[index_msg].len;1625			if (len > 16)1626				len = 16;1627 1628			for (i = 0; i < len; i += 2)1629				dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);1630			dib9000_write_word(state, 784, (u16) msg[index_msg].addr);1631			dib9000_write_word(state, 787, (len / 2) - 1);1632			dib9000_write_word(state, 786, 0);	/* start write */1633 1634			i = 1000;1635			while (dib9000_read_word(state, 791) > 0 && i)1636				i--;1637			if (i == 0)1638				dprintk("TunerITF: write failed\n");1639		}1640	}1641	return num;1642}1643 1644int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)1645{1646	struct dib9000_state *state = fe->demodulator_priv;1647 1648	state->component_bus_speed = speed;1649	return 0;1650}1651EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);1652 1653static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)1654{1655	struct dib9000_state *state = i2c_get_adapdata(i2c_adap);1656	u8 type = 0;		/* I2C */1657	u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;1658	u16 scl = state->component_bus_speed;	/* SCL frequency */1659	struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];1660	u8 p[13] = { 0 };1661 1662	p[0] = type;1663	p[1] = port;1664	p[2] = msg[0].addr << 1;1665 1666	p[3] = (u8) scl & 0xff;	/* scl */1667	p[4] = (u8) (scl >> 8);1668 1669	p[7] = 0;1670	p[8] = 0;1671 1672	p[9] = (u8) (msg[0].len);1673	p[10] = (u8) (msg[0].len >> 8);1674	if ((num > 1) && (msg[1].flags & I2C_M_RD)) {1675		p[11] = (u8) (msg[1].len);1676		p[12] = (u8) (msg[1].len >> 8);1677	} else {1678		p[11] = 0;1679		p[12] = 0;1680	}1681 1682	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {1683		dprintk("could not get the lock\n");1684		return 0;1685	}1686 1687	dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);1688 1689	{			/* write-part */1690		dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);1691		dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);1692	}1693 1694	/* do the transaction */1695	if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {1696		mutex_unlock(&state->platform.risc.mem_mbx_lock);1697		return 0;1698	}1699 1700	/* read back any possible result */1701	if ((num > 1) && (msg[1].flags & I2C_M_RD))1702		dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);1703 1704	mutex_unlock(&state->platform.risc.mem_mbx_lock);1705 1706	return num;1707}1708 1709static u32 dib9000_i2c_func(struct i2c_adapter *adapter)1710{1711	return I2C_FUNC_I2C;1712}1713 1714static const struct i2c_algorithm dib9000_tuner_algo = {1715	.master_xfer = dib9000_tuner_xfer,1716	.functionality = dib9000_i2c_func,1717};1718 1719static const struct i2c_algorithm dib9000_component_bus_algo = {1720	.master_xfer = dib9000_fw_component_bus_xfer,1721	.functionality = dib9000_i2c_func,1722};1723 1724struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)1725{1726	struct dib9000_state *st = fe->demodulator_priv;1727	return &st->tuner_adap;1728}1729EXPORT_SYMBOL(dib9000_get_tuner_interface);1730 1731struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)1732{1733	struct dib9000_state *st = fe->demodulator_priv;1734	return &st->component_bus;1735}1736EXPORT_SYMBOL(dib9000_get_component_bus_interface);1737 1738struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)1739{1740	struct dib9000_state *st = fe->demodulator_priv;1741	return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);1742}1743EXPORT_SYMBOL(dib9000_get_i2c_master);1744 1745int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)1746{1747	struct dib9000_state *st = fe->demodulator_priv;1748 1749	st->i2c.i2c_adap = i2c;1750	return 0;1751}1752EXPORT_SYMBOL(dib9000_set_i2c_adapter);1753 1754static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)1755{1756	st->gpio_dir = dib9000_read_word(st, 773);1757	st->gpio_dir &= ~(1 << num);	/* reset the direction bit */1758	st->gpio_dir |= (dir & 0x1) << num;	/* set the new direction */1759	dib9000_write_word(st, 773, st->gpio_dir);1760 1761	st->gpio_val = dib9000_read_word(st, 774);1762	st->gpio_val &= ~(1 << num);	/* reset the direction bit */1763	st->gpio_val |= (val & 0x01) << num;	/* set the new value */1764	dib9000_write_word(st, 774, st->gpio_val);1765 1766	dprintk("gpio dir: %04x: gpio val: %04x\n", st->gpio_dir, st->gpio_val);1767 1768	return 0;1769}1770 1771int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)1772{1773	struct dib9000_state *state = fe->demodulator_priv;1774	return dib9000_cfg_gpio(state, num, dir, val);1775}1776EXPORT_SYMBOL(dib9000_set_gpio);1777 1778int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)1779{1780	struct dib9000_state *state = fe->demodulator_priv;1781	u16 val;1782	int ret;1783 1784	if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {1785		/* postpone the pid filtering cmd */1786		dprintk("pid filter cmd postpone\n");1787		state->pid_ctrl_index++;1788		state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;1789		state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;1790		return 0;1791	}1792 1793	if (mutex_lock_interruptible(&state->demod_lock) < 0) {1794		dprintk("could not get the lock\n");1795		return -EINTR;1796	}1797 1798	val = dib9000_read_word(state, 294 + 1) & 0xffef;1799	val |= (onoff & 0x1) << 4;1800 1801	dprintk("PID filter enabled %d\n", onoff);1802	ret = dib9000_write_word(state, 294 + 1, val);1803	mutex_unlock(&state->demod_lock);1804	return ret;1805 1806}1807EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);1808 1809int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)1810{1811	struct dib9000_state *state = fe->demodulator_priv;1812	int ret;1813 1814	if (state->pid_ctrl_index != -2) {1815		/* postpone the pid filtering cmd */1816		dprintk("pid filter postpone\n");1817		if (state->pid_ctrl_index < 9) {1818			state->pid_ctrl_index++;1819			state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;1820			state->pid_ctrl[state->pid_ctrl_index].id = id;1821			state->pid_ctrl[state->pid_ctrl_index].pid = pid;1822			state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;1823		} else1824			dprintk("can not add any more pid ctrl cmd\n");1825		return 0;1826	}1827 1828	if (mutex_lock_interruptible(&state->demod_lock) < 0) {1829		dprintk("could not get the lock\n");1830		return -EINTR;1831	}1832	dprintk("Index %x, PID %d, OnOff %d\n", id, pid, onoff);1833	ret = dib9000_write_word(state, 300 + 1 + id,1834			onoff ? (1 << 13) | pid : 0);1835	mutex_unlock(&state->demod_lock);1836	return ret;1837}1838EXPORT_SYMBOL(dib9000_fw_pid_filter);1839 1840int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)1841{1842	struct dib9000_state *state = fe->demodulator_priv;1843	return dib9000_fw_init(state);1844}1845EXPORT_SYMBOL(dib9000_firmware_post_pll_init);1846 1847static void dib9000_release(struct dvb_frontend *demod)1848{1849	struct dib9000_state *st = demod->demodulator_priv;1850	u8 index_frontend;1851 1852	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)1853		dvb_frontend_detach(st->fe[index_frontend]);1854 1855	dibx000_exit_i2c_master(&st->i2c_master);1856 1857	i2c_del_adapter(&st->tuner_adap);1858	i2c_del_adapter(&st->component_bus);1859	kfree(st->fe[0]);1860	kfree(st);1861}1862 1863static int dib9000_wakeup(struct dvb_frontend *fe)1864{1865	return 0;1866}1867 1868static int dib9000_sleep(struct dvb_frontend *fe)1869{1870	struct dib9000_state *state = fe->demodulator_priv;1871	u8 index_frontend;1872	int ret = 0;1873 1874	if (mutex_lock_interruptible(&state->demod_lock) < 0) {1875		dprintk("could not get the lock\n");1876		return -EINTR;1877	}1878	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {1879		ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);1880		if (ret < 0)1881			goto error;1882	}1883	ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);1884 1885error:1886	mutex_unlock(&state->demod_lock);1887	return ret;1888}1889 1890static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)1891{1892	tune->min_delay_ms = 1000;1893	return 0;1894}1895 1896static int dib9000_get_frontend(struct dvb_frontend *fe,1897				struct dtv_frontend_properties *c)1898{1899	struct dib9000_state *state = fe->demodulator_priv;1900	u8 index_frontend, sub_index_frontend;1901	enum fe_status stat;1902	int ret = 0;1903 1904	if (state->get_frontend_internal == 0) {1905		if (mutex_lock_interruptible(&state->demod_lock) < 0) {1906			dprintk("could not get the lock\n");1907			return -EINTR;1908		}1909	}1910 1911	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {1912		state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);1913		if (stat & FE_HAS_SYNC) {1914			dprintk("TPS lock on the slave%i\n", index_frontend);1915 1916			/* synchronize the cache with the other frontends */1917			state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], c);1918			for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);1919			     sub_index_frontend++) {1920				if (sub_index_frontend != index_frontend) {1921					state->fe[sub_index_frontend]->dtv_property_cache.modulation =1922					    state->fe[index_frontend]->dtv_property_cache.modulation;1923					state->fe[sub_index_frontend]->dtv_property_cache.inversion =1924					    state->fe[index_frontend]->dtv_property_cache.inversion;1925					state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =1926					    state->fe[index_frontend]->dtv_property_cache.transmission_mode;1927					state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =1928					    state->fe[index_frontend]->dtv_property_cache.guard_interval;1929					state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =1930					    state->fe[index_frontend]->dtv_property_cache.hierarchy;1931					state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =1932					    state->fe[index_frontend]->dtv_property_cache.code_rate_HP;1933					state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =1934					    state->fe[index_frontend]->dtv_property_cache.code_rate_LP;1935					state->fe[sub_index_frontend]->dtv_property_cache.rolloff =1936					    state->fe[index_frontend]->dtv_property_cache.rolloff;1937				}1938			}1939			ret = 0;1940			goto return_value;1941		}1942	}1943 1944	/* get the channel from master chip */1945	ret = dib9000_fw_get_channel(fe);1946	if (ret != 0)1947		goto return_value;1948 1949	/* synchronize the cache with the other frontends */1950	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {1951		state->fe[index_frontend]->dtv_property_cache.inversion = c->inversion;1952		state->fe[index_frontend]->dtv_property_cache.transmission_mode = c->transmission_mode;1953		state->fe[index_frontend]->dtv_property_cache.guard_interval = c->guard_interval;1954		state->fe[index_frontend]->dtv_property_cache.modulation = c->modulation;1955		state->fe[index_frontend]->dtv_property_cache.hierarchy = c->hierarchy;1956		state->fe[index_frontend]->dtv_property_cache.code_rate_HP = c->code_rate_HP;1957		state->fe[index_frontend]->dtv_property_cache.code_rate_LP = c->code_rate_LP;1958		state->fe[index_frontend]->dtv_property_cache.rolloff = c->rolloff;1959	}1960	ret = 0;1961 1962return_value:1963	if (state->get_frontend_internal == 0)1964		mutex_unlock(&state->demod_lock);1965	return ret;1966}1967 1968static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)1969{1970	struct dib9000_state *state = fe->demodulator_priv;1971	state->tune_state = tune_state;1972	if (tune_state == CT_DEMOD_START)1973		state->status = FE_STATUS_TUNE_PENDING;1974 1975	return 0;1976}1977 1978static u32 dib9000_get_status(struct dvb_frontend *fe)1979{1980	struct dib9000_state *state = fe->demodulator_priv;1981	return state->status;1982}1983 1984static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)1985{1986	struct dib9000_state *state = fe->demodulator_priv;1987 1988	memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));1989	return 0;1990}1991 1992static int dib9000_set_frontend(struct dvb_frontend *fe)1993{1994	struct dib9000_state *state = fe->demodulator_priv;1995	int sleep_time, sleep_time_slave;1996	u32 frontend_status;1997	u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;1998	struct dvb_frontend_parametersContext channel_status;1999 2000	/* check that the correct parameters are set */2001	if (state->fe[0]->dtv_property_cache.frequency == 0) {2002		dprintk("dib9000: must specify frequency\n");2003		return 0;2004	}2005 2006	if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {2007		dprintk("dib9000: must specify bandwidth\n");2008		return 0;2009	}2010 2011	state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */2012	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2013		dprintk("could not get the lock\n");2014		return 0;2015	}2016 2017	fe->dtv_property_cache.delivery_system = SYS_DVBT;2018 2019	/* set the master status */2020	if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO ||2021	    state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO ||2022	    state->fe[0]->dtv_property_cache.modulation == QAM_AUTO ||2023	    state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) {2024		/* no channel specified, autosearch the channel */2025		state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;2026	} else2027		state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;2028 2029	/* set mode and status for the different frontends */2030	for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2031		dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);2032 2033		/* synchronization of the cache */2034		memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));2035 2036		state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;2037		dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);2038 2039		dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);2040		dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);2041	}2042 2043	/* actual tune */2044	exit_condition = 0;	/* 0: tune pending; 1: tune failed; 2:tune success */2045	index_frontend_success = 0;2046	do {2047		sleep_time = dib9000_fw_tune(state->fe[0]);2048		for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2049			sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);2050			if (sleep_time == FE_CALLBACK_TIME_NEVER)2051				sleep_time = sleep_time_slave;2052			else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))2053				sleep_time = sleep_time_slave;2054		}2055		if (sleep_time != FE_CALLBACK_TIME_NEVER)2056			msleep(sleep_time / 10);2057		else2058			break;2059 2060		nbr_pending = 0;2061		exit_condition = 0;2062		index_frontend_success = 0;2063		for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2064			frontend_status = -dib9000_get_status(state->fe[index_frontend]);2065			if (frontend_status > -FE_STATUS_TUNE_PENDING) {2066				exit_condition = 2;	/* tune success */2067				index_frontend_success = index_frontend;2068				break;2069			}2070			if (frontend_status == -FE_STATUS_TUNE_PENDING)2071				nbr_pending++;	/* some frontends are still tuning */2072		}2073		if ((exit_condition != 2) && (nbr_pending == 0))2074			exit_condition = 1;	/* if all tune are done and no success, exit: tune failed */2075 2076	} while (exit_condition == 0);2077 2078	/* check the tune result */2079	if (exit_condition == 1) {	/* tune failed */2080		dprintk("tune failed\n");2081		mutex_unlock(&state->demod_lock);2082		/* tune failed; put all the pid filtering cmd to junk */2083		state->pid_ctrl_index = -1;2084		return 0;2085	}2086 2087	dprintk("tune success on frontend%i\n", index_frontend_success);2088 2089	/* synchronize all the channel cache */2090	state->get_frontend_internal = 1;2091	dib9000_get_frontend(state->fe[0], &state->fe[0]->dtv_property_cache);2092	state->get_frontend_internal = 0;2093 2094	/* retune the other frontends with the found channel */2095	channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;2096	for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2097		/* only retune the frontends which was not tuned success */2098		if (index_frontend != index_frontend_success) {2099			dib9000_set_channel_status(state->fe[index_frontend], &channel_status);2100			dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);2101		}2102	}2103	do {2104		sleep_time = FE_CALLBACK_TIME_NEVER;2105		for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2106			if (index_frontend != index_frontend_success) {2107				sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);2108				if (sleep_time == FE_CALLBACK_TIME_NEVER)2109					sleep_time = sleep_time_slave;2110				else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))2111					sleep_time = sleep_time_slave;2112			}2113		}2114		if (sleep_time != FE_CALLBACK_TIME_NEVER)2115			msleep(sleep_time / 10);2116		else2117			break;2118 2119		nbr_pending = 0;2120		for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2121			if (index_frontend != index_frontend_success) {2122				frontend_status = -dib9000_get_status(state->fe[index_frontend]);2123				if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))2124					nbr_pending++;	/* some frontends are still tuning */2125			}2126		}2127	} while (nbr_pending != 0);2128 2129	/* set the output mode */2130	dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);2131	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)2132		dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);2133 2134	/* turn off the diversity for the last frontend */2135	dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);2136 2137	mutex_unlock(&state->demod_lock);2138	if (state->pid_ctrl_index >= 0) {2139		u8 index_pid_filter_cmd;2140		u8 pid_ctrl_index = state->pid_ctrl_index;2141 2142		state->pid_ctrl_index = -2;2143		for (index_pid_filter_cmd = 0;2144				index_pid_filter_cmd <= pid_ctrl_index;2145				index_pid_filter_cmd++) {2146			if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)2147				dib9000_fw_pid_filter_ctrl(state->fe[0],2148						state->pid_ctrl[index_pid_filter_cmd].onoff);2149			else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)2150				dib9000_fw_pid_filter(state->fe[0],2151						state->pid_ctrl[index_pid_filter_cmd].id,2152						state->pid_ctrl[index_pid_filter_cmd].pid,2153						state->pid_ctrl[index_pid_filter_cmd].onoff);2154		}2155	}2156	/* do not postpone any more the pid filtering */2157	state->pid_ctrl_index = -2;2158 2159	return 0;2160}2161 2162static u16 dib9000_read_lock(struct dvb_frontend *fe)2163{2164	struct dib9000_state *state = fe->demodulator_priv;2165 2166	return dib9000_read_word(state, 535);2167}2168 2169static int dib9000_read_status(struct dvb_frontend *fe, enum fe_status *stat)2170{2171	struct dib9000_state *state = fe->demodulator_priv;2172	u8 index_frontend;2173	u16 lock = 0, lock_slave = 0;2174 2175	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2176		dprintk("could not get the lock\n");2177		return -EINTR;2178	}2179	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)2180		lock_slave |= dib9000_read_lock(state->fe[index_frontend]);2181 2182	lock = dib9000_read_word(state, 535);2183 2184	*stat = 0;2185 2186	if ((lock & 0x8000) || (lock_slave & 0x8000))2187		*stat |= FE_HAS_SIGNAL;2188	if ((lock & 0x3000) || (lock_slave & 0x3000))2189		*stat |= FE_HAS_CARRIER;2190	if ((lock & 0x0100) || (lock_slave & 0x0100))2191		*stat |= FE_HAS_VITERBI;2192	if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))2193		*stat |= FE_HAS_SYNC;2194	if ((lock & 0x0008) || (lock_slave & 0x0008))2195		*stat |= FE_HAS_LOCK;2196 2197	mutex_unlock(&state->demod_lock);2198 2199	return 0;2200}2201 2202static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)2203{2204	struct dib9000_state *state = fe->demodulator_priv;2205	u16 *c;2206	int ret = 0;2207 2208	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2209		dprintk("could not get the lock\n");2210		return -EINTR;2211	}2212	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {2213		dprintk("could not get the lock\n");2214		ret = -EINTR;2215		goto error;2216	}2217	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {2218		mutex_unlock(&state->platform.risc.mem_mbx_lock);2219		ret = -EIO;2220		goto error;2221	}2222	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,2223			state->i2c_read_buffer, 16 * 2);2224	mutex_unlock(&state->platform.risc.mem_mbx_lock);2225 2226	c = (u16 *)state->i2c_read_buffer;2227 2228	*ber = c[10] << 16 | c[11];2229 2230error:2231	mutex_unlock(&state->demod_lock);2232	return ret;2233}2234 2235static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)2236{2237	struct dib9000_state *state = fe->demodulator_priv;2238	u8 index_frontend;2239	u16 *c = (u16 *)state->i2c_read_buffer;2240	u16 val;2241	int ret = 0;2242 2243	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2244		dprintk("could not get the lock\n");2245		return -EINTR;2246	}2247	*strength = 0;2248	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {2249		state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);2250		if (val > 65535 - *strength)2251			*strength = 65535;2252		else2253			*strength += val;2254	}2255 2256	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {2257		dprintk("could not get the lock\n");2258		ret = -EINTR;2259		goto error;2260	}2261	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {2262		mutex_unlock(&state->platform.risc.mem_mbx_lock);2263		ret = -EIO;2264		goto error;2265	}2266	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);2267	mutex_unlock(&state->platform.risc.mem_mbx_lock);2268 2269	val = 65535 - c[4];2270	if (val > 65535 - *strength)2271		*strength = 65535;2272	else2273		*strength += val;2274 2275error:2276	mutex_unlock(&state->demod_lock);2277	return ret;2278}2279 2280static u32 dib9000_get_snr(struct dvb_frontend *fe)2281{2282	struct dib9000_state *state = fe->demodulator_priv;2283	u16 *c = (u16 *)state->i2c_read_buffer;2284	u32 n, s, exp;2285	u16 val;2286 2287	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {2288		dprintk("could not get the lock\n");2289		return 0;2290	}2291	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {2292		mutex_unlock(&state->platform.risc.mem_mbx_lock);2293		return 0;2294	}2295	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);2296	mutex_unlock(&state->platform.risc.mem_mbx_lock);2297 2298	val = c[7];2299	n = (val >> 4) & 0xff;2300	exp = ((val & 0xf) << 2);2301	val = c[8];2302	exp += ((val >> 14) & 0x3);2303	if ((exp & 0x20) != 0)2304		exp -= 0x40;2305	n <<= exp + 16;2306 2307	s = (val >> 6) & 0xFF;2308	exp = (val & 0x3F);2309	if ((exp & 0x20) != 0)2310		exp -= 0x40;2311	s <<= exp + 16;2312 2313	if (n > 0) {2314		u32 t = (s / n) << 16;2315		return t + ((s << 16) - n * t) / n;2316	}2317	return 0xffffffff;2318}2319 2320static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)2321{2322	struct dib9000_state *state = fe->demodulator_priv;2323	u8 index_frontend;2324	u32 snr_master;2325 2326	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2327		dprintk("could not get the lock\n");2328		return -EINTR;2329	}2330	snr_master = dib9000_get_snr(fe);2331	for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)2332		snr_master += dib9000_get_snr(state->fe[index_frontend]);2333 2334	if ((snr_master >> 16) != 0) {2335		snr_master = 10 * intlog10(snr_master >> 16);2336		*snr = snr_master / ((1 << 24) / 10);2337	} else2338		*snr = 0;2339 2340	mutex_unlock(&state->demod_lock);2341 2342	return 0;2343}2344 2345static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)2346{2347	struct dib9000_state *state = fe->demodulator_priv;2348	u16 *c = (u16 *)state->i2c_read_buffer;2349	int ret = 0;2350 2351	if (mutex_lock_interruptible(&state->demod_lock) < 0) {2352		dprintk("could not get the lock\n");2353		return -EINTR;2354	}2355	if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {2356		dprintk("could not get the lock\n");2357		ret = -EINTR;2358		goto error;2359	}2360	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {2361		mutex_unlock(&state->platform.risc.mem_mbx_lock);2362		ret = -EIO;2363		goto error;2364	}2365	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);2366	mutex_unlock(&state->platform.risc.mem_mbx_lock);2367 2368	*unc = c[12];2369 2370error:2371	mutex_unlock(&state->demod_lock);2372	return ret;2373}2374 2375int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)2376{2377	int k = 0, ret = 0;2378	u8 new_addr = 0;2379	struct i2c_device client = {.i2c_adap = i2c };2380 2381	client.i2c_write_buffer = kzalloc(4, GFP_KERNEL);2382	if (!client.i2c_write_buffer) {2383		dprintk("%s: not enough memory\n", __func__);2384		return -ENOMEM;2385	}2386	client.i2c_read_buffer = kzalloc(4, GFP_KERNEL);2387	if (!client.i2c_read_buffer) {2388		dprintk("%s: not enough memory\n", __func__);2389		ret = -ENOMEM;2390		goto error_memory;2391	}2392 2393	client.i2c_addr = default_addr + 16;2394	dib9000_i2c_write16(&client, 1796, 0x0);2395 2396	for (k = no_of_demods - 1; k >= 0; k--) {2397		/* designated i2c address */2398		new_addr = first_addr + (k << 1);2399		client.i2c_addr = default_addr;2400 2401		dib9000_i2c_write16(&client, 1817, 3);2402		dib9000_i2c_write16(&client, 1796, 0);2403		dib9000_i2c_write16(&client, 1227, 1);2404		dib9000_i2c_write16(&client, 1227, 0);2405 2406		client.i2c_addr = new_addr;2407		dib9000_i2c_write16(&client, 1817, 3);2408		dib9000_i2c_write16(&client, 1796, 0);2409		dib9000_i2c_write16(&client, 1227, 1);2410		dib9000_i2c_write16(&client, 1227, 0);2411 2412		if (dib9000_identify(&client) == 0) {2413			client.i2c_addr = default_addr;2414			if (dib9000_identify(&client) == 0) {2415				dprintk("DiB9000 #%d: not identified\n", k);2416				ret = -EIO;2417				goto error;2418			}2419		}2420 2421		dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));2422		dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);2423 2424		dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);2425	}2426 2427	for (k = 0; k < no_of_demods; k++) {2428		new_addr = first_addr | (k << 1);2429		client.i2c_addr = new_addr;2430 2431		dib9000_i2c_write16(&client, 1794, (new_addr << 2));2432		dib9000_i2c_write16(&client, 1795, 0);2433	}2434 2435error:2436	kfree(client.i2c_read_buffer);2437error_memory:2438	kfree(client.i2c_write_buffer);2439 2440	return ret;2441}2442EXPORT_SYMBOL(dib9000_i2c_enumeration);2443 2444int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)2445{2446	struct dib9000_state *state = fe->demodulator_priv;2447	u8 index_frontend = 1;2448 2449	while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))2450		index_frontend++;2451	if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {2452		dprintk("set slave fe %p to index %i\n", fe_slave, index_frontend);2453		state->fe[index_frontend] = fe_slave;2454		return 0;2455	}2456 2457	dprintk("too many slave frontend\n");2458	return -ENOMEM;2459}2460EXPORT_SYMBOL(dib9000_set_slave_frontend);2461 2462struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)2463{2464	struct dib9000_state *state = fe->demodulator_priv;2465 2466	if (slave_index >= MAX_NUMBER_OF_FRONTENDS)2467		return NULL;2468	return state->fe[slave_index];2469}2470EXPORT_SYMBOL(dib9000_get_slave_frontend);2471 2472static const struct dvb_frontend_ops dib9000_ops;2473struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)2474{2475	struct dvb_frontend *fe;2476	struct dib9000_state *st;2477	st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);2478	if (st == NULL)2479		return NULL;2480	fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);2481	if (fe == NULL) {2482		kfree(st);2483		return NULL;2484	}2485 2486	memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));2487	st->i2c.i2c_adap = i2c_adap;2488	st->i2c.i2c_addr = i2c_addr;2489	st->i2c.i2c_write_buffer = st->i2c_write_buffer;2490	st->i2c.i2c_read_buffer = st->i2c_read_buffer;2491 2492	st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;2493	st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;2494	st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;2495 2496	mutex_init(&st->platform.risc.mbx_if_lock);2497	mutex_init(&st->platform.risc.mbx_lock);2498	mutex_init(&st->platform.risc.mem_lock);2499	mutex_init(&st->platform.risc.mem_mbx_lock);2500	mutex_init(&st->demod_lock);2501	st->get_frontend_internal = 0;2502 2503	st->pid_ctrl_index = -2;2504 2505	st->fe[0] = fe;2506	fe->demodulator_priv = st;2507	memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));2508 2509	/* Ensure the output mode remains at the previous default if it's2510	 * not specifically set by the caller.2511	 */2512	if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))2513		st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;2514 2515	if (dib9000_identify(&st->i2c) == 0)2516		goto error;2517 2518	dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);2519 2520	st->tuner_adap.dev.parent = i2c_adap->dev.parent;2521	strscpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS",2522		sizeof(st->tuner_adap.name));2523	st->tuner_adap.algo = &dib9000_tuner_algo;2524	st->tuner_adap.algo_data = NULL;2525	i2c_set_adapdata(&st->tuner_adap, st);2526	if (i2c_add_adapter(&st->tuner_adap) < 0)2527		goto error;2528 2529	st->component_bus.dev.parent = i2c_adap->dev.parent;2530	strscpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS",2531		sizeof(st->component_bus.name));2532	st->component_bus.algo = &dib9000_component_bus_algo;2533	st->component_bus.algo_data = NULL;2534	st->component_bus_speed = 340;2535	i2c_set_adapdata(&st->component_bus, st);2536	if (i2c_add_adapter(&st->component_bus) < 0)2537		goto component_bus_add_error;2538 2539	dib9000_fw_reset(fe);2540 2541	return fe;2542 2543component_bus_add_error:2544	i2c_del_adapter(&st->tuner_adap);2545error:2546	kfree(st);2547	return NULL;2548}2549EXPORT_SYMBOL_GPL(dib9000_attach);2550 2551static const struct dvb_frontend_ops dib9000_ops = {2552	.delsys = { SYS_DVBT },2553	.info = {2554		 .name = "DiBcom 9000",2555		 .frequency_min_hz =  44250 * kHz,2556		 .frequency_max_hz = 867250 * kHz,2557		 .frequency_stepsize_hz = 62500,2558		 .caps = FE_CAN_INVERSION_AUTO |2559		 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |2560		 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |2561		 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |2562		 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,2563		 },2564 2565	.release = dib9000_release,2566 2567	.init = dib9000_wakeup,2568	.sleep = dib9000_sleep,2569 2570	.set_frontend = dib9000_set_frontend,2571	.get_tune_settings = dib9000_fe_get_tune_settings,2572	.get_frontend = dib9000_get_frontend,2573 2574	.read_status = dib9000_read_status,2575	.read_ber = dib9000_read_ber,2576	.read_signal_strength = dib9000_read_signal_strength,2577	.read_snr = dib9000_read_snr,2578	.read_ucblocks = dib9000_read_unc_blocks,2579};2580 2581MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");2582MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");2583MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");2584MODULE_LICENSE("GPL");2585