brintos

brintos / linux-shallow public Read only

0
0
Text · 115.4 KiB · a90a9e5 Raw
3982 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* cx25840 - Conexant CX25840 audio/video decoder driver3 *4 * Copyright (C) 2004 Ulf Eklund5 *6 * Based on the saa7115 driver and on the first version of Chris Kennedy's7 * cx25840 driver.8 *9 * Changes by Tyler Trafford <tatrafford@comcast.net>10 *    - cleanup/rewrite for V4L2 API (2005)11 *12 * VBI support by Hans Verkuil <hverkuil@xs4all.nl>.13 *14 * NTSC sliced VBI support by Christopher Neufeld <television@cneufeld.ca>15 * with additional fixes by Hans Verkuil <hverkuil@xs4all.nl>.16 *17 * CX23885 support by Steven Toth <stoth@linuxtv.org>.18 *19 * CX2388[578] IRQ handling, IO Pin mux configuration and other small fixes are20 * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>21 *22 * CX23888 DIF support for the HVR185023 * Copyright (C) 2011 Steven Toth <stoth@kernellabs.com>24 *25 * CX2584x pin to pad mapping and output format configuration support are26 * Copyright (C) 2011 Maciej S. Szmigiero <mail@maciej.szmigiero.name>27 */28 29#include <linux/kernel.h>30#include <linux/module.h>31#include <linux/slab.h>32#include <linux/videodev2.h>33#include <linux/i2c.h>34#include <linux/delay.h>35#include <linux/math64.h>36#include <media/v4l2-common.h>37#include <media/drv-intf/cx25840.h>38 39#include "cx25840-core.h"40 41MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");42MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");43MODULE_LICENSE("GPL");44 45#define CX25840_VID_INT_STAT_REG 0x41046#define CX25840_VID_INT_STAT_BITS 0x0000ffff47#define CX25840_VID_INT_MASK_BITS 0xffff000048#define CX25840_VID_INT_MASK_SHFT 1649#define CX25840_VID_INT_MASK_REG 0x41250 51#define CX23885_AUD_MC_INT_MASK_REG 0x80c52#define CX23885_AUD_MC_INT_STAT_BITS 0xffff000053#define CX23885_AUD_MC_INT_CTRL_BITS 0x0000ffff54#define CX23885_AUD_MC_INT_STAT_SHFT 1655 56#define CX25840_AUD_INT_CTRL_REG 0x81257#define CX25840_AUD_INT_STAT_REG 0x81358 59#define CX23885_PIN_CTRL_IRQ_REG 0x12360#define CX23885_PIN_CTRL_IRQ_IR_STAT  0x4061#define CX23885_PIN_CTRL_IRQ_AUD_STAT 0x2062#define CX23885_PIN_CTRL_IRQ_VID_STAT 0x1063 64#define CX25840_IR_STATS_REG	0x21065#define CX25840_IR_IRQEN_REG	0x21466 67static int cx25840_debug;68 69module_param_named(debug, cx25840_debug, int, 0644);70 71MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");72 73/* ----------------------------------------------------------------------- */74static void cx23888_std_setup(struct i2c_client *client);75 76int cx25840_write(struct i2c_client *client, u16 addr, u8 value)77{78	u8 buffer[3];79 80	buffer[0] = addr >> 8;81	buffer[1] = addr & 0xff;82	buffer[2] = value;83	return i2c_master_send(client, buffer, 3);84}85 86int cx25840_write4(struct i2c_client *client, u16 addr, u32 value)87{88	u8 buffer[6];89 90	buffer[0] = addr >> 8;91	buffer[1] = addr & 0xff;92	buffer[2] = value & 0xff;93	buffer[3] = (value >> 8) & 0xff;94	buffer[4] = (value >> 16) & 0xff;95	buffer[5] = value >> 24;96	return i2c_master_send(client, buffer, 6);97}98 99u8 cx25840_read(struct i2c_client *client, u16 addr)100{101	struct i2c_msg msgs[2];102	u8 tx_buf[2], rx_buf[1];103 104	/* Write register address */105	tx_buf[0] = addr >> 8;106	tx_buf[1] = addr & 0xff;107	msgs[0].addr = client->addr;108	msgs[0].flags = 0;109	msgs[0].len = 2;110	msgs[0].buf = (char *)tx_buf;111 112	/* Read data from register */113	msgs[1].addr = client->addr;114	msgs[1].flags = I2C_M_RD;115	msgs[1].len = 1;116	msgs[1].buf = (char *)rx_buf;117 118	if (i2c_transfer(client->adapter, msgs, 2) < 2)119		return 0;120 121	return rx_buf[0];122}123 124u32 cx25840_read4(struct i2c_client *client, u16 addr)125{126	struct i2c_msg msgs[2];127	u8 tx_buf[2], rx_buf[4];128 129	/* Write register address */130	tx_buf[0] = addr >> 8;131	tx_buf[1] = addr & 0xff;132	msgs[0].addr = client->addr;133	msgs[0].flags = 0;134	msgs[0].len = 2;135	msgs[0].buf = (char *)tx_buf;136 137	/* Read data from registers */138	msgs[1].addr = client->addr;139	msgs[1].flags = I2C_M_RD;140	msgs[1].len = 4;141	msgs[1].buf = (char *)rx_buf;142 143	if (i2c_transfer(client->adapter, msgs, 2) < 2)144		return 0;145 146	return (rx_buf[3] << 24) | (rx_buf[2] << 16) | (rx_buf[1] << 8) |147		rx_buf[0];148}149 150int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned int and_mask,151		   u8 or_value)152{153	return cx25840_write(client, addr,154			     (cx25840_read(client, addr) & and_mask) |155			     or_value);156}157 158int cx25840_and_or4(struct i2c_client *client, u16 addr, u32 and_mask,159		    u32 or_value)160{161	return cx25840_write4(client, addr,162			      (cx25840_read4(client, addr) & and_mask) |163			      or_value);164}165 166/* ----------------------------------------------------------------------- */167 168static int set_input(struct i2c_client *client,169		     enum cx25840_video_input vid_input,170		     enum cx25840_audio_input aud_input);171 172/* ----------------------------------------------------------------------- */173 174static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,175				   struct v4l2_subdev_io_pin_config *p)176{177	struct i2c_client *client = v4l2_get_subdevdata(sd);178	int i;179	u32 pin_ctrl;180	u8 gpio_oe, gpio_data, strength;181 182	pin_ctrl = cx25840_read4(client, 0x120);183	gpio_oe = cx25840_read(client, 0x160);184	gpio_data = cx25840_read(client, 0x164);185 186	for (i = 0; i < n; i++) {187		strength = p[i].strength;188		if (strength > CX25840_PIN_DRIVE_FAST)189			strength = CX25840_PIN_DRIVE_FAST;190 191		switch (p[i].pin) {192		case CX23885_PIN_IRQ_N_GPIO16:193			if (p[i].function != CX23885_PAD_IRQ_N) {194				/* GPIO16 */195				pin_ctrl &= ~(0x1 << 25);196			} else {197				/* IRQ_N */198				if (p[i].flags &199					(BIT(V4L2_SUBDEV_IO_PIN_DISABLE) |200					 BIT(V4L2_SUBDEV_IO_PIN_INPUT))) {201					pin_ctrl &= ~(0x1 << 25);202				} else {203					pin_ctrl |= (0x1 << 25);204				}205				if (p[i].flags &206					BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW)) {207					pin_ctrl &= ~(0x1 << 24);208				} else {209					pin_ctrl |= (0x1 << 24);210				}211			}212			break;213		case CX23885_PIN_IR_RX_GPIO19:214			if (p[i].function != CX23885_PAD_GPIO19) {215				/* IR_RX */216				gpio_oe |= (0x1 << 0);217				pin_ctrl &= ~(0x3 << 18);218				pin_ctrl |= (strength << 18);219			} else {220				/* GPIO19 */221				gpio_oe &= ~(0x1 << 0);222				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {223					gpio_data &= ~(0x1 << 0);224					gpio_data |= ((p[i].value & 0x1) << 0);225				}226				pin_ctrl &= ~(0x3 << 12);227				pin_ctrl |= (strength << 12);228			}229			break;230		case CX23885_PIN_IR_TX_GPIO20:231			if (p[i].function != CX23885_PAD_GPIO20) {232				/* IR_TX */233				gpio_oe |= (0x1 << 1);234				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))235					pin_ctrl &= ~(0x1 << 10);236				else237					pin_ctrl |= (0x1 << 10);238				pin_ctrl &= ~(0x3 << 18);239				pin_ctrl |= (strength << 18);240			} else {241				/* GPIO20 */242				gpio_oe &= ~(0x1 << 1);243				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {244					gpio_data &= ~(0x1 << 1);245					gpio_data |= ((p[i].value & 0x1) << 1);246				}247				pin_ctrl &= ~(0x3 << 12);248				pin_ctrl |= (strength << 12);249			}250			break;251		case CX23885_PIN_I2S_SDAT_GPIO21:252			if (p[i].function != CX23885_PAD_GPIO21) {253				/* I2S_SDAT */254				/* TODO: Input or Output config */255				gpio_oe |= (0x1 << 2);256				pin_ctrl &= ~(0x3 << 22);257				pin_ctrl |= (strength << 22);258			} else {259				/* GPIO21 */260				gpio_oe &= ~(0x1 << 2);261				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {262					gpio_data &= ~(0x1 << 2);263					gpio_data |= ((p[i].value & 0x1) << 2);264				}265				pin_ctrl &= ~(0x3 << 12);266				pin_ctrl |= (strength << 12);267			}268			break;269		case CX23885_PIN_I2S_WCLK_GPIO22:270			if (p[i].function != CX23885_PAD_GPIO22) {271				/* I2S_WCLK */272				/* TODO: Input or Output config */273				gpio_oe |= (0x1 << 3);274				pin_ctrl &= ~(0x3 << 22);275				pin_ctrl |= (strength << 22);276			} else {277				/* GPIO22 */278				gpio_oe &= ~(0x1 << 3);279				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {280					gpio_data &= ~(0x1 << 3);281					gpio_data |= ((p[i].value & 0x1) << 3);282				}283				pin_ctrl &= ~(0x3 << 12);284				pin_ctrl |= (strength << 12);285			}286			break;287		case CX23885_PIN_I2S_BCLK_GPIO23:288			if (p[i].function != CX23885_PAD_GPIO23) {289				/* I2S_BCLK */290				/* TODO: Input or Output config */291				gpio_oe |= (0x1 << 4);292				pin_ctrl &= ~(0x3 << 22);293				pin_ctrl |= (strength << 22);294			} else {295				/* GPIO23 */296				gpio_oe &= ~(0x1 << 4);297				if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {298					gpio_data &= ~(0x1 << 4);299					gpio_data |= ((p[i].value & 0x1) << 4);300				}301				pin_ctrl &= ~(0x3 << 12);302				pin_ctrl |= (strength << 12);303			}304			break;305		}306	}307 308	cx25840_write(client, 0x164, gpio_data);309	cx25840_write(client, 0x160, gpio_oe);310	cx25840_write4(client, 0x120, pin_ctrl);311	return 0;312}313 314static u8 cx25840_function_to_pad(struct i2c_client *client, u8 function)315{316	if (function > CX25840_PAD_VRESET) {317		v4l_err(client, "invalid function %u, assuming default\n",318			(unsigned int)function);319		return 0;320	}321 322	return function;323}324 325static void cx25840_set_invert(u8 *pinctrl3, u8 *voutctrl4, u8 function,326			       u8 pin, bool invert)327{328	switch (function) {329	case CX25840_PAD_IRQ_N:330		if (invert)331			*pinctrl3 &= ~2;332		else333			*pinctrl3 |= 2;334		break;335 336	case CX25840_PAD_ACTIVE:337		if (invert)338			*voutctrl4 |= BIT(2);339		else340			*voutctrl4 &= ~BIT(2);341		break;342 343	case CX25840_PAD_VACTIVE:344		if (invert)345			*voutctrl4 |= BIT(5);346		else347			*voutctrl4 &= ~BIT(5);348		break;349 350	case CX25840_PAD_CBFLAG:351		if (invert)352			*voutctrl4 |= BIT(4);353		else354			*voutctrl4 &= ~BIT(4);355		break;356 357	case CX25840_PAD_VRESET:358		if (invert)359			*voutctrl4 |= BIT(0);360		else361			*voutctrl4 &= ~BIT(0);362		break;363	}364 365	if (function != CX25840_PAD_DEFAULT)366		return;367 368	switch (pin) {369	case CX25840_PIN_DVALID_PRGM0:370		if (invert)371			*voutctrl4 |= BIT(6);372		else373			*voutctrl4 &= ~BIT(6);374		break;375 376	case CX25840_PIN_HRESET_PRGM2:377		if (invert)378			*voutctrl4 |= BIT(1);379		else380			*voutctrl4 &= ~BIT(1);381		break;382	}383}384 385static int cx25840_s_io_pin_config(struct v4l2_subdev *sd, size_t n,386				   struct v4l2_subdev_io_pin_config *p)387{388	struct i2c_client *client = v4l2_get_subdevdata(sd);389	unsigned int i;390	u8 pinctrl[6], pinconf[10], voutctrl4;391 392	for (i = 0; i < 6; i++)393		pinctrl[i] = cx25840_read(client, 0x114 + i);394 395	for (i = 0; i < 10; i++)396		pinconf[i] = cx25840_read(client, 0x11c + i);397 398	voutctrl4 = cx25840_read(client, 0x407);399 400	for (i = 0; i < n; i++) {401		u8 strength = p[i].strength;402 403		if (strength != CX25840_PIN_DRIVE_SLOW &&404		    strength != CX25840_PIN_DRIVE_MEDIUM &&405		    strength != CX25840_PIN_DRIVE_FAST) {406			v4l_err(client,407				"invalid drive speed for pin %u (%u), assuming fast\n",408				(unsigned int)p[i].pin,409				(unsigned int)strength);410 411			strength = CX25840_PIN_DRIVE_FAST;412		}413 414		switch (p[i].pin) {415		case CX25840_PIN_DVALID_PRGM0:416			if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))417				pinctrl[0] &= ~BIT(6);418			else419				pinctrl[0] |= BIT(6);420 421			pinconf[3] &= 0xf0;422			pinconf[3] |= cx25840_function_to_pad(client,423							      p[i].function);424 425			cx25840_set_invert(&pinctrl[3], &voutctrl4,426					   p[i].function,427					   CX25840_PIN_DVALID_PRGM0,428					   p[i].flags &429					   BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW));430 431			pinctrl[4] &= ~(3 << 2); /* CX25840_PIN_DRIVE_MEDIUM */432			switch (strength) {433			case CX25840_PIN_DRIVE_SLOW:434				pinctrl[4] |= 1 << 2;435				break;436 437			case CX25840_PIN_DRIVE_FAST:438				pinctrl[4] |= 2 << 2;439				break;440			}441 442			break;443 444		case CX25840_PIN_HRESET_PRGM2:445			if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))446				pinctrl[1] &= ~BIT(0);447			else448				pinctrl[1] |= BIT(0);449 450			pinconf[4] &= 0xf0;451			pinconf[4] |= cx25840_function_to_pad(client,452							      p[i].function);453 454			cx25840_set_invert(&pinctrl[3], &voutctrl4,455					   p[i].function,456					   CX25840_PIN_HRESET_PRGM2,457					   p[i].flags &458					   BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW));459 460			pinctrl[4] &= ~(3 << 2); /* CX25840_PIN_DRIVE_MEDIUM */461			switch (strength) {462			case CX25840_PIN_DRIVE_SLOW:463				pinctrl[4] |= 1 << 2;464				break;465 466			case CX25840_PIN_DRIVE_FAST:467				pinctrl[4] |= 2 << 2;468				break;469			}470 471			break;472 473		case CX25840_PIN_PLL_CLK_PRGM7:474			if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))475				pinctrl[2] &= ~BIT(2);476			else477				pinctrl[2] |= BIT(2);478 479			switch (p[i].function) {480			case CX25840_PAD_XTI_X5_DLL:481				pinconf[6] = 0;482				break;483 484			case CX25840_PAD_AUX_PLL:485				pinconf[6] = 1;486				break;487 488			case CX25840_PAD_VID_PLL:489				pinconf[6] = 5;490				break;491 492			case CX25840_PAD_XTI:493				pinconf[6] = 2;494				break;495 496			default:497				pinconf[6] = 3;498				pinconf[6] |=499					cx25840_function_to_pad(client,500								p[i].function)501					<< 4;502			}503 504			break;505 506		default:507			v4l_err(client, "invalid or unsupported pin %u\n",508				(unsigned int)p[i].pin);509			break;510		}511	}512 513	cx25840_write(client, 0x407, voutctrl4);514 515	for (i = 0; i < 6; i++)516		cx25840_write(client, 0x114 + i, pinctrl[i]);517 518	for (i = 0; i < 10; i++)519		cx25840_write(client, 0x11c + i, pinconf[i]);520 521	return 0;522}523 524static int common_s_io_pin_config(struct v4l2_subdev *sd, size_t n,525				  struct v4l2_subdev_io_pin_config *pincfg)526{527	struct cx25840_state *state = to_state(sd);528 529	if (is_cx2388x(state))530		return cx23885_s_io_pin_config(sd, n, pincfg);531	else if (is_cx2584x(state))532		return cx25840_s_io_pin_config(sd, n, pincfg);533	return 0;534}535 536/* ----------------------------------------------------------------------- */537 538static void init_dll1(struct i2c_client *client)539{540	/*541	 * This is the Hauppauge sequence used to542	 * initialize the Delay Lock Loop 1 (ADC DLL).543	 */544	cx25840_write(client, 0x159, 0x23);545	cx25840_write(client, 0x15a, 0x87);546	cx25840_write(client, 0x15b, 0x06);547	udelay(10);548	cx25840_write(client, 0x159, 0xe1);549	udelay(10);550	cx25840_write(client, 0x15a, 0x86);551	cx25840_write(client, 0x159, 0xe0);552	cx25840_write(client, 0x159, 0xe1);553	cx25840_write(client, 0x15b, 0x10);554}555 556static void init_dll2(struct i2c_client *client)557{558	/*559	 * This is the Hauppauge sequence used to560	 * initialize the Delay Lock Loop 2 (ADC DLL).561	 */562	cx25840_write(client, 0x15d, 0xe3);563	cx25840_write(client, 0x15e, 0x86);564	cx25840_write(client, 0x15f, 0x06);565	udelay(10);566	cx25840_write(client, 0x15d, 0xe1);567	cx25840_write(client, 0x15d, 0xe0);568	cx25840_write(client, 0x15d, 0xe1);569}570 571static void cx25836_initialize(struct i2c_client *client)572{573	/*574	 *reset configuration is described on page 3-77575	 * of the CX25836 datasheet576	 */577 578	/* 2. */579	cx25840_and_or(client, 0x000, ~0x01, 0x01);580	cx25840_and_or(client, 0x000, ~0x01, 0x00);581	/* 3a. */582	cx25840_and_or(client, 0x15a, ~0x70, 0x00);583	/* 3b. */584	cx25840_and_or(client, 0x15b, ~0x1e, 0x06);585	/* 3c. */586	cx25840_and_or(client, 0x159, ~0x02, 0x02);587	/* 3d. */588	udelay(10);589	/* 3e. */590	cx25840_and_or(client, 0x159, ~0x02, 0x00);591	/* 3f. */592	cx25840_and_or(client, 0x159, ~0xc0, 0xc0);593	/* 3g. */594	cx25840_and_or(client, 0x159, ~0x01, 0x00);595	cx25840_and_or(client, 0x159, ~0x01, 0x01);596	/* 3h. */597	cx25840_and_or(client, 0x15b, ~0x1e, 0x10);598}599 600static void cx25840_work_handler(struct work_struct *work)601{602	struct cx25840_state *state = container_of(work, struct cx25840_state, fw_work);603 604	cx25840_loadfw(state->c);605	wake_up(&state->fw_wait);606}607 608#define CX25840_VCONFIG_SET_BIT(state, opt_msk, voc, idx, bit, oneval)	\609	do {								\610		if ((state)->vid_config & (opt_msk)) {			\611			if (((state)->vid_config & (opt_msk)) ==	\612			    (oneval))					\613				(voc)[idx] |= BIT(bit);		\614			else						\615				(voc)[idx] &= ~BIT(bit);		\616		}							\617	} while (0)618 619/* apply current vconfig to hardware regs */620static void cx25840_vconfig_apply(struct i2c_client *client)621{622	struct cx25840_state *state = to_state(i2c_get_clientdata(client));623	u8 voutctrl[3];624	unsigned int i;625 626	for (i = 0; i < 3; i++)627		voutctrl[i] = cx25840_read(client, 0x404 + i);628 629	if (state->vid_config & CX25840_VCONFIG_FMT_MASK)630		voutctrl[0] &= ~3;631	switch (state->vid_config & CX25840_VCONFIG_FMT_MASK) {632	case CX25840_VCONFIG_FMT_BT656:633		voutctrl[0] |= 1;634		break;635 636	case CX25840_VCONFIG_FMT_VIP11:637		voutctrl[0] |= 2;638		break;639 640	case CX25840_VCONFIG_FMT_VIP2:641		voutctrl[0] |= 3;642		break;643 644	case CX25840_VCONFIG_FMT_BT601:645		/* zero */646	default:647		break;648	}649 650	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_RES_MASK, voutctrl,651				0, 2, CX25840_VCONFIG_RES_10BIT);652	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VBIRAW_MASK, voutctrl,653				0, 3, CX25840_VCONFIG_VBIRAW_ENABLED);654	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_ANCDATA_MASK, voutctrl,655				0, 4, CX25840_VCONFIG_ANCDATA_ENABLED);656	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_TASKBIT_MASK, voutctrl,657				0, 5, CX25840_VCONFIG_TASKBIT_ONE);658	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_ACTIVE_MASK, voutctrl,659				1, 2, CX25840_VCONFIG_ACTIVE_HORIZONTAL);660	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VALID_MASK, voutctrl,661				1, 3, CX25840_VCONFIG_VALID_ANDACTIVE);662	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_HRESETW_MASK, voutctrl,663				1, 4, CX25840_VCONFIG_HRESETW_PIXCLK);664 665	if (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK)666		voutctrl[1] &= ~(3 << 6);667	switch (state->vid_config & CX25840_VCONFIG_CLKGATE_MASK) {668	case CX25840_VCONFIG_CLKGATE_VALID:669		voutctrl[1] |= 2;670		break;671 672	case CX25840_VCONFIG_CLKGATE_VALIDACTIVE:673		voutctrl[1] |= 3;674		break;675 676	case CX25840_VCONFIG_CLKGATE_NONE:677		/* zero */678	default:679		break;680	}681 682	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_DCMODE_MASK, voutctrl,683				2, 0, CX25840_VCONFIG_DCMODE_BYTES);684	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_IDID0S_MASK, voutctrl,685				2, 1, CX25840_VCONFIG_IDID0S_LINECNT);686	CX25840_VCONFIG_SET_BIT(state, CX25840_VCONFIG_VIPCLAMP_MASK, voutctrl,687				2, 4, CX25840_VCONFIG_VIPCLAMP_ENABLED);688 689	for (i = 0; i < 3; i++)690		cx25840_write(client, 0x404 + i, voutctrl[i]);691}692 693static void cx25840_initialize(struct i2c_client *client)694{695	DEFINE_WAIT(wait);696	struct cx25840_state *state = to_state(i2c_get_clientdata(client));697	struct workqueue_struct *q;698 699	/* datasheet startup in numbered steps, refer to page 3-77 */700	/* 2. */701	cx25840_and_or(client, 0x803, ~0x10, 0x00);702	/*703	 * The default of this register should be 4, but I get 0 instead.704	 * Set this register to 4 manually.705	 */706	cx25840_write(client, 0x000, 0x04);707	/* 3. */708	init_dll1(client);709	init_dll2(client);710	cx25840_write(client, 0x136, 0x0a);711	/* 4. */712	cx25840_write(client, 0x13c, 0x01);713	cx25840_write(client, 0x13c, 0x00);714	/* 5. */715	/*716	 * Do the firmware load in a work handler to prevent.717	 * Otherwise the kernel is blocked waiting for the718	 * bit-banging i2c interface to finish uploading the719	 * firmware.720	 */721	INIT_WORK(&state->fw_work, cx25840_work_handler);722	init_waitqueue_head(&state->fw_wait);723	q = create_singlethread_workqueue("cx25840_fw");724	if (q) {725		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);726		queue_work(q, &state->fw_work);727		schedule();728		finish_wait(&state->fw_wait, &wait);729		destroy_workqueue(q);730	}731 732	/* 6. */733	cx25840_write(client, 0x115, 0x8c);734	cx25840_write(client, 0x116, 0x07);735	cx25840_write(client, 0x118, 0x02);736	/* 7. */737	cx25840_write(client, 0x4a5, 0x80);738	cx25840_write(client, 0x4a5, 0x00);739	cx25840_write(client, 0x402, 0x00);740	/* 8. */741	cx25840_and_or(client, 0x401, ~0x18, 0);742	cx25840_and_or(client, 0x4a2, ~0x10, 0x10);743	/* steps 8c and 8d are done in change_input() */744	/* 10. */745	cx25840_write(client, 0x8d3, 0x1f);746	cx25840_write(client, 0x8e3, 0x03);747 748	cx25840_std_setup(client);749 750	/* trial and error says these are needed to get audio */751	cx25840_write(client, 0x914, 0xa0);752	cx25840_write(client, 0x918, 0xa0);753	cx25840_write(client, 0x919, 0x01);754 755	/* stereo preferred */756	cx25840_write(client, 0x809, 0x04);757	/* AC97 shift */758	cx25840_write(client, 0x8cf, 0x0f);759 760	/* (re)set input */761	set_input(client, state->vid_input, state->aud_input);762 763	if (state->generic_mode)764		cx25840_vconfig_apply(client);765 766	/* start microcontroller */767	cx25840_and_or(client, 0x803, ~0x10, 0x10);768}769 770static void cx23885_initialize(struct i2c_client *client)771{772	DEFINE_WAIT(wait);773	struct cx25840_state *state = to_state(i2c_get_clientdata(client));774	u32 clk_freq = 0;775	struct workqueue_struct *q;776 777	/* cx23885 sets hostdata to clk_freq pointer */778	if (v4l2_get_subdev_hostdata(&state->sd))779		clk_freq = *((u32 *)v4l2_get_subdev_hostdata(&state->sd));780 781	/*782	 * Come out of digital power down783	 * The CX23888, at least, needs this, otherwise registers aside from784	 * 0x0-0x2 can't be read or written.785	 */786	cx25840_write(client, 0x000, 0);787 788	/* Internal Reset */789	cx25840_and_or(client, 0x102, ~0x01, 0x01);790	cx25840_and_or(client, 0x102, ~0x01, 0x00);791 792	/* Stop microcontroller */793	cx25840_and_or(client, 0x803, ~0x10, 0x00);794 795	/* DIF in reset? */796	cx25840_write(client, 0x398, 0);797 798	/*799	 * Trust the default xtal, no division800	 * '885: 28.636363... MHz801	 * '887: 25.000000 MHz802	 * '888: 50.000000 MHz803	 */804	cx25840_write(client, 0x2, 0x76);805 806	/* Power up all the PLL's and DLL */807	cx25840_write(client, 0x1, 0x40);808 809	/* Sys PLL */810	switch (state->id) {811	case CX23888_AV:812		/*813		 * 50.0 MHz * (0xb + 0xe8ba26/0x2000000)/4 = 5 * 28.636363 MHz814		 * 572.73 MHz before post divide815		 */816		if (clk_freq == 25000000) {817			/* 888/ImpactVCBe or 25Mhz xtal */818			; /* nothing to do */819		} else {820			/* HVR1850 or 50MHz xtal */821			cx25840_write(client, 0x2, 0x71);822		}823		cx25840_write4(client, 0x11c, 0x01d1744c);824		cx25840_write4(client, 0x118, 0x00000416);825		cx25840_write4(client, 0x404, 0x0010253e);826		cx25840_write4(client, 0x42c, 0x42600000);827		cx25840_write4(client, 0x44c, 0x161f1000);828		break;829	case CX23887_AV:830		/*831		 * 25.0 MHz * (0x16 + 0x1d1744c/0x2000000)/4 = 5 * 28.636363 MHz832		 * 572.73 MHz before post divide833		 */834		cx25840_write4(client, 0x11c, 0x01d1744c);835		cx25840_write4(client, 0x118, 0x00000416);836		break;837	case CX23885_AV:838	default:839		/*840		 * 28.636363 MHz * (0x14 + 0x0/0x2000000)/4 = 5 * 28.636363 MHz841		 * 572.73 MHz before post divide842		 */843		cx25840_write4(client, 0x11c, 0x00000000);844		cx25840_write4(client, 0x118, 0x00000414);845		break;846	}847 848	/* Disable DIF bypass */849	cx25840_write4(client, 0x33c, 0x00000001);850 851	/* DIF Src phase inc */852	cx25840_write4(client, 0x340, 0x0df7df83);853 854	/*855	 * Vid PLL856	 * Setup for a BT.656 pixel clock of 13.5 Mpixels/second857	 *858	 * 28.636363 MHz * (0xf + 0x02be2c9/0x2000000)/4 = 8 * 13.5 MHz859	 * 432.0 MHz before post divide860	 */861 862	/* HVR1850 */863	switch (state->id) {864	case CX23888_AV:865		if (clk_freq == 25000000) {866			/* 888/ImpactVCBe or 25MHz xtal */867			cx25840_write4(client, 0x10c, 0x01b6db7b);868			cx25840_write4(client, 0x108, 0x00000512);869		} else {870			/* 888/HVR1250 or 50MHz xtal */871			cx25840_write4(client, 0x10c, 0x13333333);872			cx25840_write4(client, 0x108, 0x00000515);873		}874		break;875	default:876		cx25840_write4(client, 0x10c, 0x002be2c9);877		cx25840_write4(client, 0x108, 0x0000040f);878	}879 880	/* Luma */881	cx25840_write4(client, 0x414, 0x00107d12);882 883	/* Chroma */884	if (is_cx23888(state))885		cx25840_write4(client, 0x418, 0x1d008282);886	else887		cx25840_write4(client, 0x420, 0x3d008282);888 889	/*890	 * Aux PLL891	 * Initial setup for audio sample clock:892	 * 48 ksps, 16 bits/sample, x160 multiplier = 122.88 MHz893	 * Initial I2S output/master clock(?):894	 * 48 ksps, 16 bits/sample, x16 multiplier = 12.288 MHz895	 */896	switch (state->id) {897	case CX23888_AV:898		/*899		 * 50.0 MHz * (0x7 + 0x0bedfa4/0x2000000)/3 = 122.88 MHz900		 * 368.64 MHz before post divide901		 * 122.88 MHz / 0xa = 12.288 MHz902		 */903		/* HVR1850 or 50MHz xtal or 25MHz xtal */904		cx25840_write4(client, 0x114, 0x017dbf48);905		cx25840_write4(client, 0x110, 0x000a030e);906		break;907	case CX23887_AV:908		/*909		 * 25.0 MHz * (0xe + 0x17dbf48/0x2000000)/3 = 122.88 MHz910		 * 368.64 MHz before post divide911		 * 122.88 MHz / 0xa = 12.288 MHz912		 */913		cx25840_write4(client, 0x114, 0x017dbf48);914		cx25840_write4(client, 0x110, 0x000a030e);915		break;916	case CX23885_AV:917	default:918		/*919		 * 28.636363 MHz * (0xc + 0x1bf0c9e/0x2000000)/3 = 122.88 MHz920		 * 368.64 MHz before post divide921		 * 122.88 MHz / 0xa = 12.288 MHz922		 */923		cx25840_write4(client, 0x114, 0x01bf0c9e);924		cx25840_write4(client, 0x110, 0x000a030c);925		break;926	}927 928	/* ADC2 input select */929	cx25840_write(client, 0x102, 0x10);930 931	/* VIN1 & VIN5 */932	cx25840_write(client, 0x103, 0x11);933 934	/* Enable format auto detect */935	cx25840_write(client, 0x400, 0);936	/* Fast subchroma lock */937	/* White crush, Chroma AGC & Chroma Killer enabled */938	cx25840_write(client, 0x401, 0xe8);939 940	/* Select AFE clock pad output source */941	cx25840_write(client, 0x144, 0x05);942 943	/* Drive GPIO2 direction and values for HVR1700944	 * where an onboard mux selects the output of demodulator945	 * vs the 417. Failure to set this results in no DTV.946	 * It's safe to set this across all Hauppauge boards947	 * currently, regardless of the board type.948	 */949	cx25840_write(client, 0x160, 0x1d);950	cx25840_write(client, 0x164, 0x00);951 952	/*953	 * Do the firmware load in a work handler to prevent.954	 * Otherwise the kernel is blocked waiting for the955	 * bit-banging i2c interface to finish uploading the956	 * firmware.957	 */958	INIT_WORK(&state->fw_work, cx25840_work_handler);959	init_waitqueue_head(&state->fw_wait);960	q = create_singlethread_workqueue("cx25840_fw");961	if (q) {962		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);963		queue_work(q, &state->fw_work);964		schedule();965		finish_wait(&state->fw_wait, &wait);966		destroy_workqueue(q);967	}968 969	/*970	 * Call the cx23888 specific std setup func, we no longer rely on971	 * the generic cx24840 func.972	 */973	if (is_cx23888(state))974		cx23888_std_setup(client);975	else976		cx25840_std_setup(client);977 978	/* (re)set input */979	set_input(client, state->vid_input, state->aud_input);980 981	/* start microcontroller */982	cx25840_and_or(client, 0x803, ~0x10, 0x10);983 984	/* Disable and clear video interrupts - we don't use them */985	cx25840_write4(client, CX25840_VID_INT_STAT_REG, 0xffffffff);986 987	/* Disable and clear audio interrupts - we don't use them */988	cx25840_write(client, CX25840_AUD_INT_CTRL_REG, 0xff);989	cx25840_write(client, CX25840_AUD_INT_STAT_REG, 0xff);990 991	/* CC raw enable */992 993	/*994	 *  - VIP 1.1 control codes - 10bit, blue field enable.995	 *  - enable raw data during vertical blanking.996	 *  - enable ancillary Data insertion for 656 or VIP.997	 */998	cx25840_write4(client, 0x404, 0x0010253e);999 1000	/* CC on  - VBI_LINE_CTRL3, FLD_VBI_MD_LINE12 */1001	cx25840_write(client, state->vbi_regs_offset + 0x42f, 0x66);1002 1003	/* HVR-1250 / HVR1850 DIF related */1004	/* Power everything up */1005	cx25840_write4(client, 0x130, 0x0);1006 1007	/* SRC_COMB_CFG */1008	if (is_cx23888(state))1009		cx25840_write4(client, 0x454, 0x6628021F);1010	else1011		cx25840_write4(client, 0x478, 0x6628021F);1012 1013	/* AFE_CLK_OUT_CTRL - Select the clock output source as output */1014	cx25840_write4(client, 0x144, 0x5);1015 1016	/* I2C_OUT_CTL - I2S output configuration as1017	 * Master, Sony, Left justified, left sample on WS=11018	 */1019	cx25840_write4(client, 0x918, 0x1a0);1020 1021	/* AFE_DIAG_CTRL1 */1022	cx25840_write4(client, 0x134, 0x000a1800);1023 1024	/* AFE_DIAG_CTRL3 - Inverted Polarity for Audio and Video */1025	cx25840_write4(client, 0x13c, 0x00310000);1026}1027 1028/* ----------------------------------------------------------------------- */1029 1030static void cx231xx_initialize(struct i2c_client *client)1031{1032	DEFINE_WAIT(wait);1033	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1034	struct workqueue_struct *q;1035 1036	/* Internal Reset */1037	cx25840_and_or(client, 0x102, ~0x01, 0x01);1038	cx25840_and_or(client, 0x102, ~0x01, 0x00);1039 1040	/* Stop microcontroller */1041	cx25840_and_or(client, 0x803, ~0x10, 0x00);1042 1043	/* DIF in reset? */1044	cx25840_write(client, 0x398, 0);1045 1046	/* Trust the default xtal, no division */1047	/* This changes for the cx23888 products */1048	cx25840_write(client, 0x2, 0x76);1049 1050	/* Bring down the regulator for AUX clk */1051	cx25840_write(client, 0x1, 0x40);1052 1053	/* Disable DIF bypass */1054	cx25840_write4(client, 0x33c, 0x00000001);1055 1056	/* DIF Src phase inc */1057	cx25840_write4(client, 0x340, 0x0df7df83);1058 1059	/* Luma */1060	cx25840_write4(client, 0x414, 0x00107d12);1061 1062	/* Chroma */1063	cx25840_write4(client, 0x420, 0x3d008282);1064 1065	/* ADC2 input select */1066	cx25840_write(client, 0x102, 0x10);1067 1068	/* VIN1 & VIN5 */1069	cx25840_write(client, 0x103, 0x11);1070 1071	/* Enable format auto detect */1072	cx25840_write(client, 0x400, 0);1073	/* Fast subchroma lock */1074	/* White crush, Chroma AGC & Chroma Killer enabled */1075	cx25840_write(client, 0x401, 0xe8);1076 1077	/*1078	 * Do the firmware load in a work handler to prevent.1079	 * Otherwise the kernel is blocked waiting for the1080	 * bit-banging i2c interface to finish uploading the1081	 * firmware.1082	 */1083	INIT_WORK(&state->fw_work, cx25840_work_handler);1084	init_waitqueue_head(&state->fw_wait);1085	q = create_singlethread_workqueue("cx25840_fw");1086	if (q) {1087		prepare_to_wait(&state->fw_wait, &wait, TASK_UNINTERRUPTIBLE);1088		queue_work(q, &state->fw_work);1089		schedule();1090		finish_wait(&state->fw_wait, &wait);1091		destroy_workqueue(q);1092	}1093 1094	cx25840_std_setup(client);1095 1096	/* (re)set input */1097	set_input(client, state->vid_input, state->aud_input);1098 1099	/* start microcontroller */1100	cx25840_and_or(client, 0x803, ~0x10, 0x10);1101 1102	/* CC raw enable */1103	cx25840_write(client, 0x404, 0x0b);1104 1105	/* CC on */1106	cx25840_write(client, 0x42f, 0x66);1107	cx25840_write4(client, 0x474, 0x1e1e601a);1108}1109 1110/* ----------------------------------------------------------------------- */1111 1112void cx25840_std_setup(struct i2c_client *client)1113{1114	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1115	v4l2_std_id std = state->std;1116	int hblank, hactive, burst, vblank, vactive, sc;1117	int vblank656, src_decimation;1118	int luma_lpf, uv_lpf, comb;1119	u32 pll_int, pll_frac, pll_post;1120 1121	/* datasheet startup, step 8d */1122	if (std & ~V4L2_STD_NTSC)1123		cx25840_write(client, 0x49f, 0x11);1124	else1125		cx25840_write(client, 0x49f, 0x14);1126 1127	/* generic mode uses the values that the chip autoconfig would set */1128	if (std & V4L2_STD_625_50) {1129		hblank = 132;1130		hactive = 720;1131		burst = 93;1132		if (state->generic_mode) {1133			vblank = 34;1134			vactive = 576;1135			vblank656 = 38;1136		} else {1137			vblank = 36;1138			vactive = 580;1139			vblank656 = 40;1140		}1141		src_decimation = 0x21f;1142		luma_lpf = 2;1143 1144		if (std & V4L2_STD_SECAM) {1145			uv_lpf = 0;1146			comb = 0;1147			sc = 0x0a425f;1148		} else if (std == V4L2_STD_PAL_Nc) {1149			if (state->generic_mode) {1150				burst = 95;1151				luma_lpf = 1;1152			}1153			uv_lpf = 1;1154			comb = 0x20;1155			sc = 556453;1156		} else {1157			uv_lpf = 1;1158			comb = 0x20;1159			sc = 688739;1160		}1161	} else {1162		hactive = 720;1163		hblank = 122;1164		vactive = 487;1165		luma_lpf = 1;1166		uv_lpf = 1;1167		if (state->generic_mode) {1168			vblank = 20;1169			vblank656 = 24;1170		}1171 1172		src_decimation = 0x21f;1173		if (std == V4L2_STD_PAL_60) {1174			if (!state->generic_mode) {1175				vblank = 26;1176				vblank656 = 26;1177				burst = 0x5b;1178			} else {1179				burst = 0x59;1180			}1181			luma_lpf = 2;1182			comb = 0x20;1183			sc = 688739;1184		} else if (std == V4L2_STD_PAL_M) {1185			vblank = 20;1186			vblank656 = 24;1187			burst = 0x61;1188			comb = 0x20;1189			sc = 555452;1190		} else {1191			if (!state->generic_mode) {1192				vblank = 26;1193				vblank656 = 26;1194			}1195			burst = 0x5b;1196			comb = 0x66;1197			sc = 556063;1198		}1199	}1200 1201	/* DEBUG: Displays configured PLL frequency */1202	if (!is_cx231xx(state)) {1203		pll_int = cx25840_read(client, 0x108);1204		pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff;1205		pll_post = cx25840_read(client, 0x109);1206		v4l_dbg(1, cx25840_debug, client,1207			"PLL regs = int: %u, frac: %u, post: %u\n",1208			pll_int, pll_frac, pll_post);1209 1210		if (pll_post) {1211			int fin, fsc;1212			int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L;1213 1214			pll /= pll_post;1215			v4l_dbg(1, cx25840_debug, client,1216				"PLL = %d.%06d MHz\n",1217				pll / 1000000, pll % 1000000);1218			v4l_dbg(1, cx25840_debug, client,1219				"PLL/8 = %d.%06d MHz\n",1220				pll / 8000000, (pll / 8) % 1000000);1221 1222			fin = ((u64)src_decimation * pll) >> 12;1223			v4l_dbg(1, cx25840_debug, client,1224				"ADC Sampling freq = %d.%06d MHz\n",1225				fin / 1000000, fin % 1000000);1226 1227			fsc = (((u64)sc) * pll) >> 24L;1228			v4l_dbg(1, cx25840_debug, client,1229				"Chroma sub-carrier freq = %d.%06d MHz\n",1230				fsc / 1000000, fsc % 1000000);1231 1232			v4l_dbg(1, cx25840_debug, client,1233				"hblank %i, hactive %i, vblank %i, vactive %i, vblank656 %i, src_dec %i, burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, sc 0x%06x\n",1234				hblank, hactive, vblank, vactive, vblank656,1235				src_decimation, burst, luma_lpf, uv_lpf,1236				comb, sc);1237		}1238	}1239 1240	/* Sets horizontal blanking delay and active lines */1241	cx25840_write(client, 0x470, hblank);1242	cx25840_write(client, 0x471,1243		      (((hblank >> 8) & 0x3) | (hactive << 4)) & 0xff);1244	cx25840_write(client, 0x472, hactive >> 4);1245 1246	/* Sets burst gate delay */1247	cx25840_write(client, 0x473, burst);1248 1249	/* Sets vertical blanking delay and active duration */1250	cx25840_write(client, 0x474, vblank);1251	cx25840_write(client, 0x475,1252		      (((vblank >> 8) & 0x3) | (vactive << 4)) & 0xff);1253	cx25840_write(client, 0x476, vactive >> 4);1254	cx25840_write(client, 0x477, vblank656);1255 1256	/* Sets src decimation rate */1257	cx25840_write(client, 0x478, src_decimation & 0xff);1258	cx25840_write(client, 0x479, (src_decimation >> 8) & 0xff);1259 1260	/* Sets Luma and UV Low pass filters */1261	cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30));1262 1263	/* Enables comb filters */1264	cx25840_write(client, 0x47b, comb);1265 1266	/* Sets SC Step*/1267	cx25840_write(client, 0x47c, sc);1268	cx25840_write(client, 0x47d, (sc >> 8) & 0xff);1269	cx25840_write(client, 0x47e, (sc >> 16) & 0xff);1270 1271	/* Sets VBI parameters */1272	if (std & V4L2_STD_625_50) {1273		cx25840_write(client, 0x47f, 0x01);1274		state->vbi_line_offset = 5;1275	} else {1276		cx25840_write(client, 0x47f, 0x00);1277		state->vbi_line_offset = 8;1278	}1279}1280 1281/* ----------------------------------------------------------------------- */1282 1283static void input_change(struct i2c_client *client)1284{1285	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1286	v4l2_std_id std = state->std;1287 1288	/* Follow step 8c and 8d of section 3.16 in the cx25840 datasheet */1289	if (std & V4L2_STD_SECAM) {1290		cx25840_write(client, 0x402, 0);1291	} else {1292		cx25840_write(client, 0x402, 0x04);1293		cx25840_write(client, 0x49f,1294			      (std & V4L2_STD_NTSC) ? 0x14 : 0x11);1295	}1296	cx25840_and_or(client, 0x401, ~0x60, 0);1297	cx25840_and_or(client, 0x401, ~0x60, 0x60);1298 1299	/* Don't write into audio registers on cx2583x chips */1300	if (is_cx2583x(state))1301		return;1302 1303	cx25840_and_or(client, 0x810, ~0x01, 1);1304 1305	if (state->radio) {1306		cx25840_write(client, 0x808, 0xf9);1307		cx25840_write(client, 0x80b, 0x00);1308	} else if (std & V4L2_STD_525_60) {1309		/*1310		 * Certain Hauppauge PVR150 models have a hardware bug1311		 * that causes audio to drop out. For these models the1312		 * audio standard must be set explicitly.1313		 * To be precise: it affects cards with tuner models1314		 * 85, 99 and 112 (model numbers from tveeprom).1315		 */1316		int hw_fix = state->pvr150_workaround;1317 1318		if (std == V4L2_STD_NTSC_M_JP) {1319			/* Japan uses EIAJ audio standard */1320			cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7);1321		} else if (std == V4L2_STD_NTSC_M_KR) {1322			/* South Korea uses A2 audio standard */1323			cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8);1324		} else {1325			/* Others use the BTSC audio standard */1326			cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6);1327		}1328		cx25840_write(client, 0x80b, 0x00);1329	} else if (std & V4L2_STD_PAL) {1330		/* Autodetect audio standard and audio system */1331		cx25840_write(client, 0x808, 0xff);1332		/*1333		 * Since system PAL-L is pretty much non-existent and1334		 * not used by any public broadcast network, force1335		 * 6.5 MHz carrier to be interpreted as System DK,1336		 * this avoids DK audio detection instability1337		 */1338		cx25840_write(client, 0x80b, 0x00);1339	} else if (std & V4L2_STD_SECAM) {1340		/* Autodetect audio standard and audio system */1341		cx25840_write(client, 0x808, 0xff);1342		/*1343		 * If only one of SECAM-DK / SECAM-L is required, then force1344		 * 6.5MHz carrier, else autodetect it1345		 */1346		if ((std & V4L2_STD_SECAM_DK) &&1347		    !(std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {1348			/* 6.5 MHz carrier to be interpreted as System DK */1349			cx25840_write(client, 0x80b, 0x00);1350		} else if (!(std & V4L2_STD_SECAM_DK) &&1351			   (std & (V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC))) {1352			/* 6.5 MHz carrier to be interpreted as System L */1353			cx25840_write(client, 0x80b, 0x08);1354		} else {1355			/* 6.5 MHz carrier to be autodetected */1356			cx25840_write(client, 0x80b, 0x10);1357		}1358	}1359 1360	cx25840_and_or(client, 0x810, ~0x01, 0);1361}1362 1363static int set_input(struct i2c_client *client,1364		     enum cx25840_video_input vid_input,1365		     enum cx25840_audio_input aud_input)1366{1367	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1368	u8 is_composite = (vid_input >= CX25840_COMPOSITE1 &&1369			   vid_input <= CX25840_COMPOSITE8);1370	u8 is_component = (vid_input & CX25840_COMPONENT_ON) ==1371			CX25840_COMPONENT_ON;1372	u8 is_dif = (vid_input & CX25840_DIF_ON) ==1373			CX25840_DIF_ON;1374	u8 is_svideo = (vid_input & CX25840_SVIDEO_ON) ==1375			CX25840_SVIDEO_ON;1376	int luma = vid_input & 0xf0;1377	int chroma = vid_input & 0xf00;1378	u8 reg;1379	u32 val;1380 1381	v4l_dbg(1, cx25840_debug, client,1382		"decoder set video input %d, audio input %d\n",1383		vid_input, aud_input);1384 1385	if (vid_input >= CX25840_VIN1_CH1) {1386		v4l_dbg(1, cx25840_debug, client, "vid_input 0x%x\n",1387			vid_input);1388		reg = vid_input & 0xff;1389		is_composite = !is_component &&1390			       ((vid_input & CX25840_SVIDEO_ON) != CX25840_SVIDEO_ON);1391 1392		v4l_dbg(1, cx25840_debug, client, "mux cfg 0x%x comp=%d\n",1393			reg, is_composite);1394	} else if (is_composite) {1395		reg = 0xf0 + (vid_input - CX25840_COMPOSITE1);1396	} else {1397		if ((vid_input & ~0xff0) ||1398		    luma < CX25840_SVIDEO_LUMA1 ||1399		    luma > CX25840_SVIDEO_LUMA8 ||1400		    chroma < CX25840_SVIDEO_CHROMA4 ||1401		    chroma > CX25840_SVIDEO_CHROMA8) {1402			v4l_err(client, "0x%04x is not a valid video input!\n",1403				vid_input);1404			return -EINVAL;1405		}1406		reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4);1407		if (chroma >= CX25840_SVIDEO_CHROMA7) {1408			reg &= 0x3f;1409			reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2;1410		} else {1411			reg &= 0xcf;1412			reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4;1413		}1414	}1415 1416	/* The caller has previously prepared the correct routing1417	 * configuration in reg (for the cx23885) so we have no1418	 * need to attempt to flip bits for earlier av decoders.1419	 */1420	if (!is_cx2388x(state) && !is_cx231xx(state)) {1421		switch (aud_input) {1422		case CX25840_AUDIO_SERIAL:1423			/* do nothing, use serial audio input */1424			break;1425		case CX25840_AUDIO4:1426			reg &= ~0x30;1427			break;1428		case CX25840_AUDIO5:1429			reg &= ~0x30;1430			reg |= 0x10;1431			break;1432		case CX25840_AUDIO6:1433			reg &= ~0x30;1434			reg |= 0x20;1435			break;1436		case CX25840_AUDIO7:1437			reg &= ~0xc0;1438			break;1439		case CX25840_AUDIO8:1440			reg &= ~0xc0;1441			reg |= 0x40;1442			break;1443		default:1444			v4l_err(client, "0x%04x is not a valid audio input!\n",1445				aud_input);1446			return -EINVAL;1447		}1448	}1449 1450	cx25840_write(client, 0x103, reg);1451 1452	/* Set INPUT_MODE to Composite, S-Video or Component */1453	if (is_component)1454		cx25840_and_or(client, 0x401, ~0x6, 0x6);1455	else1456		cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02);1457 1458	if (is_cx2388x(state)) {1459		/* Enable or disable the DIF for tuner use */1460		if (is_dif) {1461			cx25840_and_or(client, 0x102, ~0x80, 0x80);1462 1463			/* Set of defaults for NTSC and PAL */1464			cx25840_write4(client, 0x31c, 0xc2262600);1465			cx25840_write4(client, 0x320, 0xc2262600);1466 1467			/* 18271 IF - Nobody else yet uses a different1468			 * tuner with the DIF, so these are reasonable1469			 * assumptions (HVR1250 and HVR1850 specific).1470			 */1471			cx25840_write4(client, 0x318, 0xda262600);1472			cx25840_write4(client, 0x33c, 0x2a24c800);1473			cx25840_write4(client, 0x104, 0x0704dd00);1474		} else {1475			cx25840_write4(client, 0x300, 0x015c28f5);1476 1477			cx25840_and_or(client, 0x102, ~0x80, 0);1478			cx25840_write4(client, 0x340, 0xdf7df83);1479			cx25840_write4(client, 0x104, 0x0704dd80);1480			cx25840_write4(client, 0x314, 0x22400600);1481			cx25840_write4(client, 0x318, 0x40002600);1482			cx25840_write4(client, 0x324, 0x40002600);1483			cx25840_write4(client, 0x32c, 0x0250e620);1484			cx25840_write4(client, 0x39c, 0x01FF0B00);1485 1486			cx25840_write4(client, 0x410, 0xffff0dbf);1487			cx25840_write4(client, 0x414, 0x00137d03);1488 1489			if (is_cx23888(state)) {1490				/* 888 MISC_TIM_CTRL */1491				cx25840_write4(client, 0x42c, 0x42600000);1492				/* 888 FIELD_COUNT */1493				cx25840_write4(client, 0x430, 0x0000039b);1494				/* 888 VSCALE_CTRL */1495				cx25840_write4(client, 0x438, 0x00000000);1496				/* 888 DFE_CTRL1 */1497				cx25840_write4(client, 0x440, 0xF8E3E824);1498				/* 888 DFE_CTRL2 */1499				cx25840_write4(client, 0x444, 0x401040dc);1500				/* 888 DFE_CTRL3 */1501				cx25840_write4(client, 0x448, 0xcd3f02a0);1502				/* 888 PLL_CTRL */1503				cx25840_write4(client, 0x44c, 0x161f1000);1504				/* 888 HTL_CTRL */1505				cx25840_write4(client, 0x450, 0x00000802);1506			}1507			cx25840_write4(client, 0x91c, 0x01000000);1508			cx25840_write4(client, 0x8e0, 0x03063870);1509			cx25840_write4(client, 0x8d4, 0x7FFF0024);1510			cx25840_write4(client, 0x8d0, 0x00063073);1511 1512			cx25840_write4(client, 0x8c8, 0x00010000);1513			cx25840_write4(client, 0x8cc, 0x00080023);1514 1515			/* DIF BYPASS */1516			cx25840_write4(client, 0x33c, 0x2a04c800);1517		}1518 1519		/* Reset the DIF */1520		cx25840_write4(client, 0x398, 0);1521	}1522 1523	if (!is_cx2388x(state) && !is_cx231xx(state)) {1524		/* Set CH_SEL_ADC2 to 1 if input comes from CH3 */1525		cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0);1526		/* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2&CH3 */1527		if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30)1528			cx25840_and_or(client, 0x102, ~0x4, 4);1529		else1530			cx25840_and_or(client, 0x102, ~0x4, 0);1531	} else {1532		/* Set DUAL_MODE_ADC2 to 1 if component*/1533		cx25840_and_or(client, 0x102, ~0x4, is_component ? 0x4 : 0x0);1534		if (is_composite) {1535			/* ADC2 input select channel 2 */1536			cx25840_and_or(client, 0x102, ~0x2, 0);1537		} else if (!is_component) {1538			/* S-Video */1539			if (chroma >= CX25840_SVIDEO_CHROMA7) {1540				/* ADC2 input select channel 3 */1541				cx25840_and_or(client, 0x102, ~0x2, 2);1542			} else {1543				/* ADC2 input select channel 2 */1544				cx25840_and_or(client, 0x102, ~0x2, 0);1545			}1546		}1547 1548		/* cx23885 / SVIDEO */1549		if (is_cx2388x(state) && is_svideo) {1550#define AFE_CTRL  (0x104)1551#define MODE_CTRL (0x400)1552			cx25840_and_or(client, 0x102, ~0x2, 0x2);1553 1554			val = cx25840_read4(client, MODE_CTRL);1555			val &= 0xFFFFF9FF;1556 1557			/* YC */1558			val |= 0x00000200;1559			val &= ~0x2000;1560			cx25840_write4(client, MODE_CTRL, val);1561 1562			val = cx25840_read4(client, AFE_CTRL);1563 1564			/* Chroma in select */1565			val |= 0x00001000;1566			val &= 0xfffffe7f;1567			/* Clear VGA_SEL_CH2 and VGA_SEL_CH3 (bits 7 and 8).1568			 * This sets them to use video rather than audio.1569			 * Only one of the two will be in use.1570			 */1571			cx25840_write4(client, AFE_CTRL, val);1572		} else {1573			cx25840_and_or(client, 0x102, ~0x2, 0);1574		}1575	}1576 1577	state->vid_input = vid_input;1578	state->aud_input = aud_input;1579	cx25840_audio_set_path(client);1580	input_change(client);1581 1582	if (is_cx2388x(state)) {1583		/* Audio channel 1 src : Parallel 1 */1584		cx25840_write(client, 0x124, 0x03);1585 1586		/* Select AFE clock pad output source */1587		cx25840_write(client, 0x144, 0x05);1588 1589		/* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */1590		cx25840_write(client, 0x914, 0xa0);1591 1592		/* I2S_OUT_CTL:1593		 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=11594		 * I2S_OUT_MASTER_MODE = Master1595		 */1596		cx25840_write(client, 0x918, 0xa0);1597		cx25840_write(client, 0x919, 0x01);1598	} else if (is_cx231xx(state)) {1599		/* Audio channel 1 src : Parallel 1 */1600		cx25840_write(client, 0x124, 0x03);1601 1602		/* I2S_IN_CTL: I2S_IN_SONY_MODE, LEFT SAMPLE on WS=1 */1603		cx25840_write(client, 0x914, 0xa0);1604 1605		/* I2S_OUT_CTL:1606		 * I2S_IN_SONY_MODE, LEFT SAMPLE on WS=11607		 * I2S_OUT_MASTER_MODE = Master1608		 */1609		cx25840_write(client, 0x918, 0xa0);1610		cx25840_write(client, 0x919, 0x01);1611	}1612 1613	if (is_cx2388x(state) &&1614	    ((aud_input == CX25840_AUDIO7) || (aud_input == CX25840_AUDIO6))) {1615		/* Configure audio from LR1 or LR2 input */1616		cx25840_write4(client, 0x910, 0);1617		cx25840_write4(client, 0x8d0, 0x63073);1618	} else if (is_cx2388x(state) && (aud_input == CX25840_AUDIO8)) {1619		/* Configure audio from tuner/sif input */1620		cx25840_write4(client, 0x910, 0x12b000c9);1621		cx25840_write4(client, 0x8d0, 0x1f063870);1622	}1623 1624	if (is_cx23888(state)) {1625		/*1626		 * HVR18501627		 *1628		 * AUD_IO_CTRL - I2S Input, Parallel11629		 *  - Channel 1 src - Parallel1 (Merlin out)1630		 *  - Channel 2 src - Parallel2 (Merlin out)1631		 *  - Channel 3 src - Parallel3 (Merlin AC97 out)1632		 *  - I2S source and dir - Merlin, output1633		 */1634		cx25840_write4(client, 0x124, 0x100);1635 1636		if (!is_dif) {1637			/*1638			 * Stop microcontroller if we don't need it1639			 * to avoid audio popping on svideo/composite use.1640			 */1641			cx25840_and_or(client, 0x803, ~0x10, 0x00);1642		}1643	}1644 1645	return 0;1646}1647 1648/* ----------------------------------------------------------------------- */1649 1650static int set_v4lstd(struct i2c_client *client)1651{1652	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1653	u8 fmt = 0;	/* zero is autodetect */1654	u8 pal_m = 0;1655 1656	/* First tests should be against specific std */1657	if (state->std == V4L2_STD_NTSC_M_JP) {1658		fmt = 0x2;1659	} else if (state->std == V4L2_STD_NTSC_443) {1660		fmt = 0x3;1661	} else if (state->std == V4L2_STD_PAL_M) {1662		pal_m = 1;1663		fmt = 0x5;1664	} else if (state->std == V4L2_STD_PAL_N) {1665		fmt = 0x6;1666	} else if (state->std == V4L2_STD_PAL_Nc) {1667		fmt = 0x7;1668	} else if (state->std == V4L2_STD_PAL_60) {1669		fmt = 0x8;1670	} else {1671		/* Then, test against generic ones */1672		if (state->std & V4L2_STD_NTSC)1673			fmt = 0x1;1674		else if (state->std & V4L2_STD_PAL)1675			fmt = 0x4;1676		else if (state->std & V4L2_STD_SECAM)1677			fmt = 0xc;1678	}1679 1680	v4l_dbg(1, cx25840_debug, client,1681		"changing video std to fmt %i\n", fmt);1682 1683	/*1684	 * Follow step 9 of section 3.16 in the cx25840 datasheet.1685	 * Without this PAL may display a vertical ghosting effect.1686	 * This happens for example with the Yuan MPC622.1687	 */1688	if (fmt >= 4 && fmt < 8) {1689		/* Set format to NTSC-M */1690		cx25840_and_or(client, 0x400, ~0xf, 1);1691		/* Turn off LCOMB */1692		cx25840_and_or(client, 0x47b, ~6, 0);1693	}1694	cx25840_and_or(client, 0x400, ~0xf, fmt);1695	cx25840_and_or(client, 0x403, ~0x3, pal_m);1696	if (is_cx23888(state))1697		cx23888_std_setup(client);1698	else1699		cx25840_std_setup(client);1700	if (!is_cx2583x(state))1701		input_change(client);1702	return 0;1703}1704 1705/* ----------------------------------------------------------------------- */1706 1707static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl)1708{1709	struct v4l2_subdev *sd = to_sd(ctrl);1710	struct cx25840_state *state = to_state(sd);1711	struct i2c_client *client = v4l2_get_subdevdata(sd);1712 1713	switch (ctrl->id) {1714	case V4L2_CID_BRIGHTNESS:1715		cx25840_write(client, 0x414, ctrl->val - 128);1716		break;1717 1718	case V4L2_CID_CONTRAST:1719		cx25840_write(client, 0x415, ctrl->val << 1);1720		break;1721 1722	case V4L2_CID_SATURATION:1723		if (is_cx23888(state)) {1724			cx25840_write(client, 0x418, ctrl->val << 1);1725			cx25840_write(client, 0x419, ctrl->val << 1);1726		} else {1727			cx25840_write(client, 0x420, ctrl->val << 1);1728			cx25840_write(client, 0x421, ctrl->val << 1);1729		}1730		break;1731 1732	case V4L2_CID_HUE:1733		if (is_cx23888(state))1734			cx25840_write(client, 0x41a, ctrl->val);1735		else1736			cx25840_write(client, 0x422, ctrl->val);1737		break;1738 1739	default:1740		return -EINVAL;1741	}1742 1743	return 0;1744}1745 1746/* ----------------------------------------------------------------------- */1747 1748static int cx25840_set_fmt(struct v4l2_subdev *sd,1749			   struct v4l2_subdev_state *sd_state,1750			   struct v4l2_subdev_format *format)1751{1752	struct v4l2_mbus_framefmt *fmt = &format->format;1753	struct cx25840_state *state = to_state(sd);1754	struct i2c_client *client = v4l2_get_subdevdata(sd);1755	u32 hsc, vsc, v_src, h_src, v_add;1756	int filter;1757	int is_50hz = !(state->std & V4L2_STD_525_60);1758 1759	if (format->pad || fmt->code != MEDIA_BUS_FMT_FIXED)1760		return -EINVAL;1761 1762	fmt->field = V4L2_FIELD_INTERLACED;1763	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;1764 1765	if (is_cx23888(state)) {1766		v_src = (cx25840_read(client, 0x42a) & 0x3f) << 4;1767		v_src |= (cx25840_read(client, 0x429) & 0xf0) >> 4;1768	} else {1769		v_src = (cx25840_read(client, 0x476) & 0x3f) << 4;1770		v_src |= (cx25840_read(client, 0x475) & 0xf0) >> 4;1771	}1772 1773	if (is_cx23888(state)) {1774		h_src = (cx25840_read(client, 0x426) & 0x3f) << 4;1775		h_src |= (cx25840_read(client, 0x425) & 0xf0) >> 4;1776	} else {1777		h_src = (cx25840_read(client, 0x472) & 0x3f) << 4;1778		h_src |= (cx25840_read(client, 0x471) & 0xf0) >> 4;1779	}1780 1781	if (!state->generic_mode) {1782		v_add = is_50hz ? 4 : 7;1783 1784		/*1785		 * cx23888 in 525-line mode is programmed for 486 active lines1786		 * while other chips use 487 active lines.1787		 *1788		 * See reg 0x428 bits [21:12] in cx23888_std_setup() vs1789		 * vactive in cx25840_std_setup().1790		 */1791		if (is_cx23888(state) && !is_50hz)1792			v_add--;1793	} else {1794		v_add = 0;1795	}1796 1797	if (h_src == 0 ||1798	    v_src <= v_add) {1799		v4l_err(client,1800			"chip reported picture size (%u x %u) is far too small\n",1801			(unsigned int)h_src, (unsigned int)v_src);1802		/*1803		 * that's the best we can do since the output picture1804		 * size is completely unknown in this case1805		 */1806		return -EINVAL;1807	}1808 1809	fmt->width = clamp(fmt->width, (h_src + 15) / 16, h_src);1810 1811	if (v_add * 8 >= v_src)1812		fmt->height = clamp(fmt->height, (u32)1, v_src - v_add);1813	else1814		fmt->height = clamp(fmt->height, (v_src - v_add * 8 + 7) / 8,1815				    v_src - v_add);1816 1817	if (format->which == V4L2_SUBDEV_FORMAT_TRY)1818		return 0;1819 1820	hsc = (h_src * (1 << 20)) / fmt->width - (1 << 20);1821	vsc = (1 << 16) - (v_src * (1 << 9) / (fmt->height + v_add) - (1 << 9));1822	vsc &= 0x1fff;1823 1824	if (fmt->width >= 385)1825		filter = 0;1826	else if (fmt->width > 192)1827		filter = 1;1828	else if (fmt->width > 96)1829		filter = 2;1830	else1831		filter = 3;1832 1833	v4l_dbg(1, cx25840_debug, client,1834		"decoder set size %u x %u with scale %x x %x\n",1835		(unsigned int)fmt->width, (unsigned int)fmt->height,1836		(unsigned int)hsc, (unsigned int)vsc);1837 1838	/* HSCALE=hsc */1839	if (is_cx23888(state)) {1840		cx25840_write4(client, 0x434, hsc | (1 << 24));1841		/* VSCALE=vsc VS_INTRLACE=1 VFILT=filter */1842		cx25840_write4(client, 0x438, vsc | (1 << 19) | (filter << 16));1843	} else {1844		cx25840_write(client, 0x418, hsc & 0xff);1845		cx25840_write(client, 0x419, (hsc >> 8) & 0xff);1846		cx25840_write(client, 0x41a, hsc >> 16);1847		/* VSCALE=vsc */1848		cx25840_write(client, 0x41c, vsc & 0xff);1849		cx25840_write(client, 0x41d, vsc >> 8);1850		/* VS_INTRLACE=1 VFILT=filter */1851		cx25840_write(client, 0x41e, 0x8 | filter);1852	}1853	return 0;1854}1855 1856/* ----------------------------------------------------------------------- */1857 1858static void log_video_status(struct i2c_client *client)1859{1860	static const char *const fmt_strs[] = {1861		"0x0",1862		"NTSC-M", "NTSC-J", "NTSC-4.43",1863		"PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60",1864		"0x9", "0xA", "0xB",1865		"SECAM",1866		"0xD", "0xE", "0xF"1867	};1868 1869	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1870	u8 vidfmt_sel = cx25840_read(client, 0x400) & 0xf;1871	u8 gen_stat1 = cx25840_read(client, 0x40d);1872	u8 gen_stat2 = cx25840_read(client, 0x40e);1873	int vid_input = state->vid_input;1874 1875	v4l_info(client, "Video signal:              %spresent\n",1876		 (gen_stat2 & 0x20) ? "" : "not ");1877	v4l_info(client, "Detected format:           %s\n",1878		 fmt_strs[gen_stat1 & 0xf]);1879 1880	v4l_info(client, "Specified standard:        %s\n",1881		 vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");1882 1883	if (vid_input >= CX25840_COMPOSITE1 &&1884	    vid_input <= CX25840_COMPOSITE8) {1885		v4l_info(client, "Specified video input:     Composite %d\n",1886			 vid_input - CX25840_COMPOSITE1 + 1);1887	} else {1888		v4l_info(client,1889			 "Specified video input:     S-Video (Luma In%d, Chroma In%d)\n",1890			 (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);1891	}1892 1893	v4l_info(client, "Specified audioclock freq: %d Hz\n",1894		 state->audclk_freq);1895}1896 1897/* ----------------------------------------------------------------------- */1898 1899static void log_audio_status(struct i2c_client *client)1900{1901	struct cx25840_state *state = to_state(i2c_get_clientdata(client));1902	u8 download_ctl = cx25840_read(client, 0x803);1903	u8 mod_det_stat0 = cx25840_read(client, 0x804);1904	u8 mod_det_stat1 = cx25840_read(client, 0x805);1905	u8 audio_config = cx25840_read(client, 0x808);1906	u8 pref_mode = cx25840_read(client, 0x809);1907	u8 afc0 = cx25840_read(client, 0x80b);1908	u8 mute_ctl = cx25840_read(client, 0x8d3);1909	int aud_input = state->aud_input;1910	char *p;1911 1912	switch (mod_det_stat0) {1913	case 0x00:1914		p = "mono";1915		break;1916	case 0x01:1917		p = "stereo";1918		break;1919	case 0x02:1920		p = "dual";1921		break;1922	case 0x04:1923		p = "tri";1924		break;1925	case 0x10:1926		p = "mono with SAP";1927		break;1928	case 0x11:1929		p = "stereo with SAP";1930		break;1931	case 0x12:1932		p = "dual with SAP";1933		break;1934	case 0x14:1935		p = "tri with SAP";1936		break;1937	case 0xfe:1938		p = "forced mode";1939		break;1940	default:1941		p = "not defined";1942	}1943	v4l_info(client, "Detected audio mode:       %s\n", p);1944 1945	switch (mod_det_stat1) {1946	case 0x00:1947		p = "not defined";1948		break;1949	case 0x01:1950		p = "EIAJ";1951		break;1952	case 0x02:1953		p = "A2-M";1954		break;1955	case 0x03:1956		p = "A2-BG";1957		break;1958	case 0x04:1959		p = "A2-DK1";1960		break;1961	case 0x05:1962		p = "A2-DK2";1963		break;1964	case 0x06:1965		p = "A2-DK3";1966		break;1967	case 0x07:1968		p = "A1 (6.0 MHz FM Mono)";1969		break;1970	case 0x08:1971		p = "AM-L";1972		break;1973	case 0x09:1974		p = "NICAM-BG";1975		break;1976	case 0x0a:1977		p = "NICAM-DK";1978		break;1979	case 0x0b:1980		p = "NICAM-I";1981		break;1982	case 0x0c:1983		p = "NICAM-L";1984		break;1985	case 0x0d:1986		p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)";1987		break;1988	case 0x0e:1989		p = "IF FM Radio";1990		break;1991	case 0x0f:1992		p = "BTSC";1993		break;1994	case 0x10:1995		p = "high-deviation FM";1996		break;1997	case 0x11:1998		p = "very high-deviation FM";1999		break;2000	case 0xfd:2001		p = "unknown audio standard";2002		break;2003	case 0xfe:2004		p = "forced audio standard";2005		break;2006	case 0xff:2007		p = "no detected audio standard";2008		break;2009	default:2010		p = "not defined";2011	}2012	v4l_info(client, "Detected audio standard:   %s\n", p);2013	v4l_info(client, "Audio microcontroller:     %s\n",2014		 (download_ctl & 0x10) ?2015		 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");2016 2017	switch (audio_config >> 4) {2018	case 0x00:2019		p = "undefined";2020		break;2021	case 0x01:2022		p = "BTSC";2023		break;2024	case 0x02:2025		p = "EIAJ";2026		break;2027	case 0x03:2028		p = "A2-M";2029		break;2030	case 0x04:2031		p = "A2-BG";2032		break;2033	case 0x05:2034		p = "A2-DK1";2035		break;2036	case 0x06:2037		p = "A2-DK2";2038		break;2039	case 0x07:2040		p = "A2-DK3";2041		break;2042	case 0x08:2043		p = "A1 (6.0 MHz FM Mono)";2044		break;2045	case 0x09:2046		p = "AM-L";2047		break;2048	case 0x0a:2049		p = "NICAM-BG";2050		break;2051	case 0x0b:2052		p = "NICAM-DK";2053		break;2054	case 0x0c:2055		p = "NICAM-I";2056		break;2057	case 0x0d:2058		p = "NICAM-L";2059		break;2060	case 0x0e:2061		p = "FM radio";2062		break;2063	case 0x0f:2064		p = "automatic detection";2065		break;2066	default:2067		p = "undefined";2068	}2069	v4l_info(client, "Configured audio standard: %s\n", p);2070 2071	if ((audio_config >> 4) < 0xF) {2072		switch (audio_config & 0xF) {2073		case 0x00:2074			p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)";2075			break;2076		case 0x01:2077			p = "MONO2 (LANGUAGE B)";2078			break;2079		case 0x02:2080			p = "MONO3 (STEREO forced MONO)";2081			break;2082		case 0x03:2083			p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)";2084			break;2085		case 0x04:2086			p = "STEREO";2087			break;2088		case 0x05:2089			p = "DUAL1 (AB)";2090			break;2091		case 0x06:2092			p = "DUAL2 (AC) (FM)";2093			break;2094		case 0x07:2095			p = "DUAL3 (BC) (FM)";2096			break;2097		case 0x08:2098			p = "DUAL4 (AC) (AM)";2099			break;2100		case 0x09:2101			p = "DUAL5 (BC) (AM)";2102			break;2103		case 0x0a:2104			p = "SAP";2105			break;2106		default:2107			p = "undefined";2108		}2109		v4l_info(client, "Configured audio mode:     %s\n", p);2110	} else {2111		switch (audio_config & 0xF) {2112		case 0x00:2113			p = "BG";2114			break;2115		case 0x01:2116			p = "DK1";2117			break;2118		case 0x02:2119			p = "DK2";2120			break;2121		case 0x03:2122			p = "DK3";2123			break;2124		case 0x04:2125			p = "I";2126			break;2127		case 0x05:2128			p = "L";2129			break;2130		case 0x06:2131			p = "BTSC";2132			break;2133		case 0x07:2134			p = "EIAJ";2135			break;2136		case 0x08:2137			p = "A2-M";2138			break;2139		case 0x09:2140			p = "FM Radio";2141			break;2142		case 0x0f:2143			p = "automatic standard and mode detection";2144			break;2145		default:2146			p = "undefined";2147		}2148		v4l_info(client, "Configured audio system:   %s\n", p);2149	}2150 2151	if (aud_input) {2152		v4l_info(client, "Specified audio input:     Tuner (In%d)\n",2153			 aud_input);2154	} else {2155		v4l_info(client, "Specified audio input:     External\n");2156	}2157 2158	switch (pref_mode & 0xf) {2159	case 0:2160		p = "mono/language A";2161		break;2162	case 1:2163		p = "language B";2164		break;2165	case 2:2166		p = "language C";2167		break;2168	case 3:2169		p = "analog fallback";2170		break;2171	case 4:2172		p = "stereo";2173		break;2174	case 5:2175		p = "language AC";2176		break;2177	case 6:2178		p = "language BC";2179		break;2180	case 7:2181		p = "language AB";2182		break;2183	default:2184		p = "undefined";2185	}2186	v4l_info(client, "Preferred audio mode:      %s\n", p);2187 2188	if ((audio_config & 0xf) == 0xf) {2189		switch ((afc0 >> 3) & 0x3) {2190		case 0:2191			p = "system DK";2192			break;2193		case 1:2194			p = "system L";2195			break;2196		case 2:2197			p = "autodetect";2198			break;2199		default:2200			p = "undefined";2201		}2202		v4l_info(client, "Selected 65 MHz format:    %s\n", p);2203 2204		switch (afc0 & 0x7) {2205		case 0:2206			p = "chroma";2207			break;2208		case 1:2209			p = "BTSC";2210			break;2211		case 2:2212			p = "EIAJ";2213			break;2214		case 3:2215			p = "A2-M";2216			break;2217		case 4:2218			p = "autodetect";2219			break;2220		default:2221			p = "undefined";2222		}2223		v4l_info(client, "Selected 45 MHz format:    %s\n", p);2224	}2225}2226 2227#define CX25840_VCONFIG_OPTION(state, cfg_in, opt_msk)			\2228	do {								\2229		if ((cfg_in) & (opt_msk)) {				\2230			(state)->vid_config &= ~(opt_msk);		\2231			(state)->vid_config |= (cfg_in) & (opt_msk);	\2232		}							\2233	} while (0)2234 2235/* apply incoming options to the current vconfig */2236static void cx25840_vconfig_add(struct cx25840_state *state, u32 cfg_in)2237{2238	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_FMT_MASK);2239	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_RES_MASK);2240	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VBIRAW_MASK);2241	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_ANCDATA_MASK);2242	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_TASKBIT_MASK);2243	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_ACTIVE_MASK);2244	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VALID_MASK);2245	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_HRESETW_MASK);2246	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_CLKGATE_MASK);2247	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_DCMODE_MASK);2248	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_IDID0S_MASK);2249	CX25840_VCONFIG_OPTION(state, cfg_in, CX25840_VCONFIG_VIPCLAMP_MASK);2250}2251 2252/* ----------------------------------------------------------------------- */2253 2254/*2255 * Initializes the device in the generic mode.2256 * For cx2584x chips also adds additional video output settings provided2257 * in @val parameter (CX25840_VCONFIG_*).2258 *2259 * The generic mode disables some of the ivtv-related hacks in this driver.2260 * For cx2584x chips it also enables setting video output configuration while2261 * setting it according to datasheet defaults by default.2262 */2263static int cx25840_init(struct v4l2_subdev *sd, u32 val)2264{2265	struct cx25840_state *state = to_state(sd);2266 2267	state->generic_mode = true;2268 2269	if (is_cx2584x(state)) {2270		/* set datasheet video output defaults */2271		state->vid_config = CX25840_VCONFIG_FMT_BT656 |2272				    CX25840_VCONFIG_RES_8BIT |2273				    CX25840_VCONFIG_VBIRAW_DISABLED |2274				    CX25840_VCONFIG_ANCDATA_ENABLED |2275				    CX25840_VCONFIG_TASKBIT_ONE |2276				    CX25840_VCONFIG_ACTIVE_HORIZONTAL |2277				    CX25840_VCONFIG_VALID_NORMAL |2278				    CX25840_VCONFIG_HRESETW_NORMAL |2279				    CX25840_VCONFIG_CLKGATE_NONE |2280				    CX25840_VCONFIG_DCMODE_DWORDS |2281				    CX25840_VCONFIG_IDID0S_NORMAL |2282				    CX25840_VCONFIG_VIPCLAMP_DISABLED;2283 2284		/* add additional settings */2285		cx25840_vconfig_add(state, val);2286	} else {2287		/* TODO: generic mode needs to be developed for other chips */2288		WARN_ON(1);2289	}2290 2291	return 0;2292}2293 2294static int cx25840_reset(struct v4l2_subdev *sd, u32 val)2295{2296	struct cx25840_state *state = to_state(sd);2297	struct i2c_client *client = v4l2_get_subdevdata(sd);2298 2299	if (is_cx2583x(state))2300		cx25836_initialize(client);2301	else if (is_cx2388x(state))2302		cx23885_initialize(client);2303	else if (is_cx231xx(state))2304		cx231xx_initialize(client);2305	else2306		cx25840_initialize(client);2307 2308	state->is_initialized = 1;2309 2310	return 0;2311}2312 2313/*2314 * This load_fw operation must be called to load the driver's firmware.2315 * This will load the firmware on the first invocation (further ones are NOP).2316 * Without this the audio standard detection will fail and you will2317 * only get mono.2318 * Alternatively, you can call the reset operation instead of this one.2319 *2320 * Since loading the firmware is often problematic when the driver is2321 * compiled into the kernel I recommend postponing calling this function2322 * until the first open of the video device. Another reason for2323 * postponing it is that loading this firmware takes a long time (seconds)2324 * due to the slow i2c bus speed. So it will speed up the boot process if2325 * you can avoid loading the fw as long as the video device isn't used.2326 */2327static int cx25840_load_fw(struct v4l2_subdev *sd)2328{2329	struct cx25840_state *state = to_state(sd);2330 2331	if (!state->is_initialized) {2332		/* initialize and load firmware */2333		cx25840_reset(sd, 0);2334	}2335	return 0;2336}2337 2338#ifdef CONFIG_VIDEO_ADV_DEBUG2339static int cx25840_g_register(struct v4l2_subdev *sd,2340			      struct v4l2_dbg_register *reg)2341{2342	struct i2c_client *client = v4l2_get_subdevdata(sd);2343 2344	reg->size = 1;2345	reg->val = cx25840_read(client, reg->reg & 0x0fff);2346	return 0;2347}2348 2349static int cx25840_s_register(struct v4l2_subdev *sd,2350			      const struct v4l2_dbg_register *reg)2351{2352	struct i2c_client *client = v4l2_get_subdevdata(sd);2353 2354	cx25840_write(client, reg->reg & 0x0fff, reg->val & 0xff);2355	return 0;2356}2357#endif2358 2359static int cx25840_s_audio_stream(struct v4l2_subdev *sd, int enable)2360{2361	struct cx25840_state *state = to_state(sd);2362	struct i2c_client *client = v4l2_get_subdevdata(sd);2363	u8 v;2364 2365	if (is_cx2583x(state) || is_cx2388x(state) || is_cx231xx(state))2366		return 0;2367 2368	v4l_dbg(1, cx25840_debug, client, "%s audio output\n",2369		enable ? "enable" : "disable");2370 2371	if (enable) {2372		v = cx25840_read(client, 0x115) | 0x80;2373		cx25840_write(client, 0x115, v);2374		v = cx25840_read(client, 0x116) | 0x03;2375		cx25840_write(client, 0x116, v);2376	} else {2377		v = cx25840_read(client, 0x115) & ~(0x80);2378		cx25840_write(client, 0x115, v);2379		v = cx25840_read(client, 0x116) & ~(0x03);2380		cx25840_write(client, 0x116, v);2381	}2382	return 0;2383}2384 2385static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)2386{2387	struct cx25840_state *state = to_state(sd);2388	struct i2c_client *client = v4l2_get_subdevdata(sd);2389	u8 v;2390 2391	v4l_dbg(1, cx25840_debug, client, "%s video output\n",2392		enable ? "enable" : "disable");2393 2394	/*2395	 * It's not clear what should be done for these devices.2396	 * The original code used the same addresses as for the cx25840, but2397	 * those addresses do something else entirely on the cx2388x and2398	 * cx231xx. Since it never did anything in the first place, just do2399	 * nothing.2400	 */2401	if (is_cx2388x(state) || is_cx231xx(state))2402		return 0;2403 2404	if (enable) {2405		v = cx25840_read(client, 0x115) | 0x0c;2406		cx25840_write(client, 0x115, v);2407		v = cx25840_read(client, 0x116) | 0x04;2408		cx25840_write(client, 0x116, v);2409	} else {2410		v = cx25840_read(client, 0x115) & ~(0x0c);2411		cx25840_write(client, 0x115, v);2412		v = cx25840_read(client, 0x116) & ~(0x04);2413		cx25840_write(client, 0x116, v);2414	}2415	return 0;2416}2417 2418/* Query the current detected video format */2419static int cx25840_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)2420{2421	struct i2c_client *client = v4l2_get_subdevdata(sd);2422 2423	static const v4l2_std_id stds[] = {2424		/* 0000 */ V4L2_STD_UNKNOWN,2425 2426		/* 0001 */ V4L2_STD_NTSC_M,2427		/* 0010 */ V4L2_STD_NTSC_M_JP,2428		/* 0011 */ V4L2_STD_NTSC_443,2429		/* 0100 */ V4L2_STD_PAL,2430		/* 0101 */ V4L2_STD_PAL_M,2431		/* 0110 */ V4L2_STD_PAL_N,2432		/* 0111 */ V4L2_STD_PAL_Nc,2433		/* 1000 */ V4L2_STD_PAL_60,2434 2435		/* 1001 */ V4L2_STD_UNKNOWN,2436		/* 1010 */ V4L2_STD_UNKNOWN,2437		/* 1011 */ V4L2_STD_UNKNOWN,2438		/* 1100 */ V4L2_STD_SECAM,2439		/* 1101 */ V4L2_STD_UNKNOWN,2440		/* 1110 */ V4L2_STD_UNKNOWN,2441		/* 1111 */ V4L2_STD_UNKNOWN2442	};2443 2444	u32 fmt = (cx25840_read4(client, 0x40c) >> 8) & 0xf;2445	*std = stds[fmt];2446 2447	v4l_dbg(1, cx25840_debug, client,2448		"querystd fmt = %x, v4l2_std_id = 0x%x\n",2449		fmt, (unsigned int)stds[fmt]);2450 2451	return 0;2452}2453 2454static int cx25840_g_input_status(struct v4l2_subdev *sd, u32 *status)2455{2456	struct i2c_client *client = v4l2_get_subdevdata(sd);2457 2458	/*2459	 * A limited function that checks for signal status and returns2460	 * the state.2461	 */2462 2463	/* Check for status of Horizontal lock (SRC lock isn't reliable) */2464	if ((cx25840_read4(client, 0x40c) & 0x00010000) == 0)2465		*status |= V4L2_IN_ST_NO_SIGNAL;2466 2467	return 0;2468}2469 2470static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)2471{2472	struct cx25840_state *state = to_state(sd);2473 2474	*std = state->std;2475 2476	return 0;2477}2478 2479static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)2480{2481	struct cx25840_state *state = to_state(sd);2482	struct i2c_client *client = v4l2_get_subdevdata(sd);2483 2484	if (state->radio == 0 && state->std == std)2485		return 0;2486	state->radio = 0;2487	state->std = std;2488	return set_v4lstd(client);2489}2490 2491static int cx25840_s_radio(struct v4l2_subdev *sd)2492{2493	struct cx25840_state *state = to_state(sd);2494 2495	state->radio = 1;2496	return 0;2497}2498 2499static int cx25840_s_video_routing(struct v4l2_subdev *sd,2500				   u32 input, u32 output, u32 config)2501{2502	struct cx25840_state *state = to_state(sd);2503	struct i2c_client *client = v4l2_get_subdevdata(sd);2504 2505	if (is_cx23888(state))2506		cx23888_std_setup(client);2507 2508	if (is_cx2584x(state) && state->generic_mode && config) {2509		cx25840_vconfig_add(state, config);2510		cx25840_vconfig_apply(client);2511	}2512 2513	return set_input(client, input, state->aud_input);2514}2515 2516static int cx25840_s_audio_routing(struct v4l2_subdev *sd,2517				   u32 input, u32 output, u32 config)2518{2519	struct cx25840_state *state = to_state(sd);2520	struct i2c_client *client = v4l2_get_subdevdata(sd);2521 2522	if (is_cx23888(state))2523		cx23888_std_setup(client);2524	return set_input(client, state->vid_input, input);2525}2526 2527static int cx25840_s_frequency(struct v4l2_subdev *sd,2528			       const struct v4l2_frequency *freq)2529{2530	struct i2c_client *client = v4l2_get_subdevdata(sd);2531 2532	input_change(client);2533	return 0;2534}2535 2536static int cx25840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)2537{2538	struct cx25840_state *state = to_state(sd);2539	struct i2c_client *client = v4l2_get_subdevdata(sd);2540	u8 vpres = cx25840_read(client, 0x40e) & 0x20;2541	u8 mode;2542	int val = 0;2543 2544	if (state->radio)2545		return 0;2546 2547	vt->signal = vpres ? 0xffff : 0x0;2548	if (is_cx2583x(state))2549		return 0;2550 2551	vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |2552			  V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;2553 2554	mode = cx25840_read(client, 0x804);2555 2556	/* get rxsubchans and audmode */2557	if ((mode & 0xf) == 1)2558		val |= V4L2_TUNER_SUB_STEREO;2559	else2560		val |= V4L2_TUNER_SUB_MONO;2561 2562	if (mode == 2 || mode == 4)2563		val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;2564 2565	if (mode & 0x10)2566		val |= V4L2_TUNER_SUB_SAP;2567 2568	vt->rxsubchans = val;2569	vt->audmode = state->audmode;2570	return 0;2571}2572 2573static int cx25840_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)2574{2575	struct cx25840_state *state = to_state(sd);2576	struct i2c_client *client = v4l2_get_subdevdata(sd);2577 2578	if (state->radio || is_cx2583x(state))2579		return 0;2580 2581	switch (vt->audmode) {2582	case V4L2_TUNER_MODE_MONO:2583		/*2584		 * mono      -> mono2585		 * stereo    -> mono2586		 * bilingual -> lang12587		 */2588		cx25840_and_or(client, 0x809, ~0xf, 0x00);2589		break;2590	case V4L2_TUNER_MODE_STEREO:2591	case V4L2_TUNER_MODE_LANG1:2592		/*2593		 * mono      -> mono2594		 * stereo    -> stereo2595		 * bilingual -> lang12596		 */2597		cx25840_and_or(client, 0x809, ~0xf, 0x04);2598		break;2599	case V4L2_TUNER_MODE_LANG1_LANG2:2600		/*2601		 * mono      -> mono2602		 * stereo    -> stereo2603		 * bilingual -> lang1/lang22604		 */2605		cx25840_and_or(client, 0x809, ~0xf, 0x07);2606		break;2607	case V4L2_TUNER_MODE_LANG2:2608		/*2609		 * mono      -> mono2610		 * stereo    -> stereo2611		 * bilingual -> lang22612		 */2613		cx25840_and_or(client, 0x809, ~0xf, 0x01);2614		break;2615	default:2616		return -EINVAL;2617	}2618	state->audmode = vt->audmode;2619	return 0;2620}2621 2622static int cx25840_log_status(struct v4l2_subdev *sd)2623{2624	struct cx25840_state *state = to_state(sd);2625	struct i2c_client *client = v4l2_get_subdevdata(sd);2626 2627	log_video_status(client);2628	if (!is_cx2583x(state))2629		log_audio_status(client);2630	cx25840_ir_log_status(sd);2631	v4l2_ctrl_handler_log_status(&state->hdl, sd->name);2632	return 0;2633}2634 2635static int cx23885_irq_handler(struct v4l2_subdev *sd, u32 status,2636			       bool *handled)2637{2638	struct cx25840_state *state = to_state(sd);2639	struct i2c_client *c = v4l2_get_subdevdata(sd);2640	u8 irq_stat, aud_stat, aud_en, ir_stat, ir_en;2641	u32 vid_stat, aud_mc_stat;2642	bool block_handled;2643	int ret = 0;2644 2645	irq_stat = cx25840_read(c, CX23885_PIN_CTRL_IRQ_REG);2646	v4l_dbg(2, cx25840_debug, c, "AV Core IRQ status (entry): %s %s %s\n",2647		irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT ? "ir" : "  ",2648		irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT ? "aud" : "   ",2649		irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT ? "vid" : "   ");2650 2651	if ((is_cx23885(state) || is_cx23887(state))) {2652		ir_stat = cx25840_read(c, CX25840_IR_STATS_REG);2653		ir_en = cx25840_read(c, CX25840_IR_IRQEN_REG);2654		v4l_dbg(2, cx25840_debug, c,2655			"AV Core ir IRQ status: %#04x disables: %#04x\n",2656			ir_stat, ir_en);2657		if (irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT) {2658			block_handled = false;2659			ret = cx25840_ir_irq_handler(sd,2660						     status, &block_handled);2661			if (block_handled)2662				*handled = true;2663		}2664	}2665 2666	aud_stat = cx25840_read(c, CX25840_AUD_INT_STAT_REG);2667	aud_en = cx25840_read(c, CX25840_AUD_INT_CTRL_REG);2668	v4l_dbg(2, cx25840_debug, c,2669		"AV Core audio IRQ status: %#04x disables: %#04x\n",2670		aud_stat, aud_en);2671	aud_mc_stat = cx25840_read4(c, CX23885_AUD_MC_INT_MASK_REG);2672	v4l_dbg(2, cx25840_debug, c,2673		"AV Core audio MC IRQ status: %#06x enables: %#06x\n",2674		aud_mc_stat >> CX23885_AUD_MC_INT_STAT_SHFT,2675		aud_mc_stat & CX23885_AUD_MC_INT_CTRL_BITS);2676	if (irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT) {2677		if (aud_stat) {2678			cx25840_write(c, CX25840_AUD_INT_STAT_REG, aud_stat);2679			*handled = true;2680		}2681	}2682 2683	vid_stat = cx25840_read4(c, CX25840_VID_INT_STAT_REG);2684	v4l_dbg(2, cx25840_debug, c,2685		"AV Core video IRQ status: %#06x disables: %#06x\n",2686		vid_stat & CX25840_VID_INT_STAT_BITS,2687		vid_stat >> CX25840_VID_INT_MASK_SHFT);2688	if (irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT) {2689		if (vid_stat & CX25840_VID_INT_STAT_BITS) {2690			cx25840_write4(c, CX25840_VID_INT_STAT_REG, vid_stat);2691			*handled = true;2692		}2693	}2694 2695	irq_stat = cx25840_read(c, CX23885_PIN_CTRL_IRQ_REG);2696	v4l_dbg(2, cx25840_debug, c, "AV Core IRQ status (exit): %s %s %s\n",2697		irq_stat & CX23885_PIN_CTRL_IRQ_IR_STAT ? "ir" : "  ",2698		irq_stat & CX23885_PIN_CTRL_IRQ_AUD_STAT ? "aud" : "   ",2699		irq_stat & CX23885_PIN_CTRL_IRQ_VID_STAT ? "vid" : "   ");2700 2701	return ret;2702}2703 2704static int cx25840_irq_handler(struct v4l2_subdev *sd, u32 status,2705			       bool *handled)2706{2707	struct cx25840_state *state = to_state(sd);2708 2709	*handled = false;2710 2711	/* Only support the CX2388[578] AV Core for now */2712	if (is_cx2388x(state))2713		return cx23885_irq_handler(sd, status, handled);2714 2715	return -ENODEV;2716}2717 2718/* ----------------------------------------------------------------------- */2719 2720#define DIF_PLL_FREQ_WORD	(0x300)2721#define DIF_BPF_COEFF01		(0x348)2722#define DIF_BPF_COEFF23		(0x34c)2723#define DIF_BPF_COEFF45		(0x350)2724#define DIF_BPF_COEFF67		(0x354)2725#define DIF_BPF_COEFF89		(0x358)2726#define DIF_BPF_COEFF1011	(0x35c)2727#define DIF_BPF_COEFF1213	(0x360)2728#define DIF_BPF_COEFF1415	(0x364)2729#define DIF_BPF_COEFF1617	(0x368)2730#define DIF_BPF_COEFF1819	(0x36c)2731#define DIF_BPF_COEFF2021	(0x370)2732#define DIF_BPF_COEFF2223	(0x374)2733#define DIF_BPF_COEFF2425	(0x378)2734#define DIF_BPF_COEFF2627	(0x37c)2735#define DIF_BPF_COEFF2829	(0x380)2736#define DIF_BPF_COEFF3031	(0x384)2737#define DIF_BPF_COEFF3233	(0x388)2738#define DIF_BPF_COEFF3435	(0x38c)2739#define DIF_BPF_COEFF36		(0x390)2740 2741static const u32 ifhz_coeffs[][19] = {2742	{	// 3.0 MHz2743		0x00000002, 0x00080012, 0x001e0024, 0x001bfff8,2744		0xffb4ff50, 0xfed8fe68, 0xfe24fe34, 0xfebaffc7,2745		0x014d031f, 0x04f0065d, 0x07010688, 0x04c901d6,2746		0xfe00f9d3, 0xf600f342, 0xf235f337, 0xf64efb22,2747		0x0105070f, 0x0c460fce, 0x110d0000,2748	}, {	// 3.1 MHz2749		0x00000001, 0x00070012, 0x00220032, 0x00370026,2750		0xfff0ff91, 0xff0efe7c, 0xfe01fdcc, 0xfe0afedb,2751		0x00440224, 0x0434060c, 0x0738074e, 0x06090361,2752		0xff99fb39, 0xf6fef3b6, 0xf21af2a5, 0xf573fa33,2753		0x0034067d, 0x0bfb0fb9, 0x110d0000,2754	}, {	// 3.2 MHz2755		0x00000000, 0x0004000e, 0x00200038, 0x004c004f,2756		0x002fffdf, 0xff5cfeb6, 0xfe0dfd92, 0xfd7ffe03,2757		0xff36010a, 0x03410575, 0x072607d2, 0x071804d5,2758		0x0134fcb7, 0xf81ff451, 0xf223f22e, 0xf4a7f94b,2759		0xff6405e8, 0x0bae0fa4, 0x110d0000,2760	}, {	// 3.3 MHz2761		0x0000ffff, 0x00000008, 0x001a0036, 0x0056006d,2762		0x00670030, 0xffbdff10, 0xfe46fd8d, 0xfd25fd4f,2763		0xfe35ffe0, 0x0224049f, 0x06c9080e, 0x07ef0627,2764		0x02c9fe45, 0xf961f513, 0xf250f1d2, 0xf3ecf869,2765		0xfe930552, 0x0b5f0f8f, 0x110d0000,2766	}, {	// 3.4 MHz2767		0xfffffffe, 0xfffd0001, 0x000f002c, 0x0054007d,2768		0x0093007c, 0x0024ff82, 0xfea6fdbb, 0xfd03fcca,2769		0xfd51feb9, 0x00eb0392, 0x06270802, 0x08880750,2770		0x044dffdb, 0xfabdf5f8, 0xf2a0f193, 0xf342f78f,2771		0xfdc404b9, 0x0b0e0f78, 0x110d0000,2772	}, {	// 3.5 MHz2773		0xfffffffd, 0xfffafff9, 0x0002001b, 0x0046007d,2774		0x00ad00ba, 0x00870000, 0xff26fe1a, 0xfd1bfc7e,2775		0xfc99fda4, 0xffa5025c, 0x054507ad, 0x08dd0847,2776		0x05b80172, 0xfc2ef6ff, 0xf313f170, 0xf2abf6bd,2777		0xfcf6041f, 0x0abc0f61, 0x110d0000,2778	}, {	// 3.6 MHz2779		0xfffffffd, 0xfff8fff3, 0xfff50006, 0x002f006c,2780		0x00b200e3, 0x00dc007e, 0xffb9fea0, 0xfd6bfc71,2781		0xfc17fcb1, 0xfe65010b, 0x042d0713, 0x08ec0906,2782		0x07020302, 0xfdaff823, 0xf3a7f16a, 0xf228f5f5,2783		0xfc2a0384, 0x0a670f4a, 0x110d0000,2784	}, {	// 3.7 MHz2785		0x0000fffd, 0xfff7ffef, 0xffe9fff1, 0x0010004d,2786		0x00a100f2, 0x011a00f0, 0x0053ff44, 0xfdedfca2,2787		0xfbd3fbef, 0xfd39ffae, 0x02ea0638, 0x08b50987,2788		0x08230483, 0xff39f960, 0xf45bf180, 0xf1b8f537,2789		0xfb6102e7, 0x0a110f32, 0x110d0000,2790	}, {	// 3.8 MHz2791		0x0000fffe, 0xfff9ffee, 0xffe1ffdd, 0xfff00024,2792		0x007c00e5, 0x013a014a, 0x00e6fff8, 0xfe98fd0f,2793		0xfbd3fb67, 0xfc32fe54, 0x01880525, 0x083909c7,2794		0x091505ee, 0x00c7fab3, 0xf52df1b4, 0xf15df484,2795		0xfa9b0249, 0x09ba0f19, 0x110d0000,2796	}, {	// 3.9 MHz2797		0x00000000, 0xfffbfff0, 0xffdeffcf, 0xffd1fff6,2798		0x004800be, 0x01390184, 0x016300ac, 0xff5efdb1,2799		0xfc17fb23, 0xfb5cfd0d, 0x001703e4, 0x077b09c4,2800		0x09d2073c, 0x0251fc18, 0xf61cf203, 0xf118f3dc,2801		0xf9d801aa, 0x09600eff, 0x110d0000,2802	}, {	// 4.0 MHz2803		0x00000001, 0xfffefff4, 0xffe1ffc8, 0xffbaffca,2804		0x000b0082, 0x01170198, 0x01c10152, 0x0030fe7b,2805		0xfc99fb24, 0xfac3fbe9, 0xfea5027f, 0x0683097f,2806		0x0a560867, 0x03d2fd89, 0xf723f26f, 0xf0e8f341,2807		0xf919010a, 0x09060ee5, 0x110d0000,2808	}, {	// 4.1 MHz2809		0x00010002, 0x0002fffb, 0xffe8ffca, 0xffacffa4,2810		0xffcd0036, 0x00d70184, 0x01f601dc, 0x00ffff60,2811		0xfd51fb6d, 0xfa6efaf5, 0xfd410103, 0x055708f9,2812		0x0a9e0969, 0x0543ff02, 0xf842f2f5, 0xf0cef2b2,2813		0xf85e006b, 0x08aa0ecb, 0x110d0000,2814	}, {	// 4.2 MHz2815		0x00010003, 0x00050003, 0xfff3ffd3, 0xffaaff8b,2816		0xff95ffe5, 0x0080014a, 0x01fe023f, 0x01ba0050,2817		0xfe35fbf8, 0xfa62fa3b, 0xfbf9ff7e, 0x04010836,2818		0x0aa90a3d, 0x069f007f, 0xf975f395, 0xf0cbf231,2819		0xf7a9ffcb, 0x084c0eaf, 0x110d0000,2820	}, {	// 4.3 MHz2821		0x00010003, 0x0008000a, 0x0000ffe4, 0xffb4ff81,2822		0xff6aff96, 0x001c00f0, 0x01d70271, 0x0254013b,2823		0xff36fcbd, 0xfa9ff9c5, 0xfadbfdfe, 0x028c073b,2824		0x0a750adf, 0x07e101fa, 0xfab8f44e, 0xf0ddf1be,2825		0xf6f9ff2b, 0x07ed0e94, 0x110d0000,2826	}, {	// 4.4 MHz2827		0x00000003, 0x0009000f, 0x000efff8, 0xffc9ff87,2828		0xff52ff54, 0xffb5007e, 0x01860270, 0x02c00210,2829		0x0044fdb2, 0xfb22f997, 0xf9f2fc90, 0x0102060f,2830		0x0a050b4c, 0x0902036e, 0xfc0af51e, 0xf106f15a,2831		0xf64efe8b, 0x078d0e77, 0x110d0000,2832	}, {	// 4.5 MHz2833		0x00000002, 0x00080012, 0x0019000e, 0xffe5ff9e,2834		0xff4fff25, 0xff560000, 0x0112023b, 0x02f702c0,2835		0x014dfec8, 0xfbe5f9b3, 0xf947fb41, 0xff7004b9,2836		0x095a0b81, 0x0a0004d8, 0xfd65f603, 0xf144f104,2837		0xf5aafdec, 0x072b0e5a, 0x110d0000,2838	}, {	// 4.6 MHz2839		0x00000001, 0x00060012, 0x00200022, 0x0005ffc1,2840		0xff61ff10, 0xff09ff82, 0x008601d7, 0x02f50340,2841		0x0241fff0, 0xfcddfa19, 0xf8e2fa1e, 0xfde30343,2842		0x08790b7f, 0x0ad50631, 0xfec7f6fc, 0xf198f0bd,2843		0xf50dfd4e, 0x06c90e3d, 0x110d0000,2844	}, {	// 4.7 MHz2845		0x0000ffff, 0x0003000f, 0x00220030, 0x0025ffed,2846		0xff87ff15, 0xfed6ff10, 0xffed014c, 0x02b90386,2847		0x03110119, 0xfdfefac4, 0xf8c6f92f, 0xfc6701b7,2848		0x07670b44, 0x0b7e0776, 0x002df807, 0xf200f086,2849		0xf477fcb1, 0x06650e1e, 0x110d0000,2850	}, {	// 4.8 MHz2851		0xfffffffe, 0xffff0009, 0x001e0038, 0x003f001b,2852		0xffbcff36, 0xfec2feb6, 0xff5600a5, 0x0248038d,2853		0x03b00232, 0xff39fbab, 0xf8f4f87f, 0xfb060020,2854		0x062a0ad2, 0x0bf908a3, 0x0192f922, 0xf27df05e,2855		0xf3e8fc14, 0x06000e00, 0x110d0000,2856	}, {	// 4.9 MHz2857		0xfffffffd, 0xfffc0002, 0x00160037, 0x00510046,2858		0xfff9ff6d, 0xfed0fe7c, 0xfecefff0, 0x01aa0356,2859		0x0413032b, 0x007ffcc5, 0xf96cf812, 0xf9cefe87,2860		0x04c90a2c, 0x0c4309b4, 0x02f3fa4a, 0xf30ef046,2861		0xf361fb7a, 0x059b0de0, 0x110d0000,2862	}, {	// 5.0 MHz2863		0xfffffffd, 0xfff9fffa, 0x000a002d, 0x00570067,2864		0x0037ffb5, 0xfefffe68, 0xfe62ff3d, 0x00ec02e3,2865		0x043503f6, 0x01befe05, 0xfa27f7ee, 0xf8c6fcf8,2866		0x034c0954, 0x0c5c0aa4, 0x044cfb7e, 0xf3b1f03f,2867		0xf2e2fae1, 0x05340dc0, 0x110d0000,2868	}, {	// 5.1 MHz2869		0x0000fffd, 0xfff8fff4, 0xfffd001e, 0x0051007b,2870		0x006e0006, 0xff48fe7c, 0xfe1bfe9a, 0x001d023e,2871		0x04130488, 0x02e6ff5b, 0xfb1ef812, 0xf7f7fb7f,2872		0x01bc084e, 0x0c430b72, 0x059afcba, 0xf467f046,2873		0xf26cfa4a, 0x04cd0da0, 0x110d0000,2874	}, {	// 5.2 MHz2875		0x0000fffe, 0xfff8ffef, 0xfff00009, 0x003f007f,2876		0x00980056, 0xffa5feb6, 0xfe00fe15, 0xff4b0170,2877		0x03b004d7, 0x03e800b9, 0xfc48f87f, 0xf768fa23,2878		0x0022071f, 0x0bf90c1b, 0x06dafdfd, 0xf52df05e,2879		0xf1fef9b5, 0x04640d7f, 0x110d0000,2880	}, {	// 5.3 MHz2881		0x0000ffff, 0xfff9ffee, 0xffe6fff3, 0x00250072,2882		0x00af009c, 0x000cff10, 0xfe13fdb8, 0xfe870089,2883		0x031104e1, 0x04b8020f, 0xfd98f92f, 0xf71df8f0,2884		0xfe8805ce, 0x0b7e0c9c, 0x0808ff44, 0xf603f086,2885		0xf19af922, 0x03fb0d5e, 0x110d0000,2886	}, {	// 5.4 MHz2887		0x00000001, 0xfffcffef, 0xffe0ffe0, 0x00050056,2888		0x00b000d1, 0x0071ff82, 0xfe53fd8c, 0xfddfff99,2889		0x024104a3, 0x054a034d, 0xff01fa1e, 0xf717f7ed,2890		0xfcf50461, 0x0ad50cf4, 0x0921008d, 0xf6e7f0bd,2891		0xf13ff891, 0x03920d3b, 0x110d0000,2892	}, {	// 5.5 MHz2893		0x00010002, 0xfffffff3, 0xffdeffd1, 0xffe5002f,2894		0x009c00ed, 0x00cb0000, 0xfebafd94, 0xfd61feb0,2895		0x014d0422, 0x05970464, 0x0074fb41, 0xf759f721,2896		0xfb7502de, 0x0a000d21, 0x0a2201d4, 0xf7d9f104,2897		0xf0edf804, 0x03280d19, 0x110d0000,2898	}, {	// 5.6 MHz2899		0x00010003, 0x0003fffa, 0xffe3ffc9, 0xffc90002,2900		0x007500ef, 0x010e007e, 0xff3dfdcf, 0xfd16fddd,2901		0x00440365, 0x059b0548, 0x01e3fc90, 0xf7dff691,2902		0xfa0f014d, 0x09020d23, 0x0b0a0318, 0xf8d7f15a,2903		0xf0a5f779, 0x02bd0cf6, 0x110d0000,2904	}, {	// 5.7 MHz2905		0x00010003, 0x00060001, 0xffecffc9, 0xffb4ffd4,2906		0x004000d5, 0x013600f0, 0xffd3fe39, 0xfd04fd31,2907		0xff360277, 0x055605ef, 0x033efdfe, 0xf8a5f642,2908		0xf8cbffb6, 0x07e10cfb, 0x0bd50456, 0xf9dff1be,2909		0xf067f6f2, 0x02520cd2, 0x110d0000,2910	}, {	// 5.8 MHz2911		0x00000003, 0x00080009, 0xfff8ffd2, 0xffaaffac,2912		0x000200a3, 0x013c014a, 0x006dfec9, 0xfd2bfcb7,2913		0xfe350165, 0x04cb0651, 0x0477ff7e, 0xf9a5f635,2914		0xf7b1fe20, 0x069f0ca8, 0x0c81058b, 0xfaf0f231,2915		0xf033f66d, 0x01e60cae, 0x110d0000,2916	}, {	// 5.9 MHz2917		0x00000002, 0x0009000e, 0x0005ffe1, 0xffacff90,2918		0xffc5005f, 0x01210184, 0x00fcff72, 0xfd8afc77,2919		0xfd51003f, 0x04020669, 0x05830103, 0xfad7f66b,2920		0xf6c8fc93, 0x05430c2b, 0x0d0d06b5, 0xfc08f2b2,2921		0xf00af5ec, 0x017b0c89, 0x110d0000,2922	}, {	// 6.0 MHz2923		0x00000001, 0x00070012, 0x0012fff5, 0xffbaff82,2924		0xff8e000f, 0x00e80198, 0x01750028, 0xfe18fc75,2925		0xfc99ff15, 0x03050636, 0x0656027f, 0xfc32f6e2,2926		0xf614fb17, 0x03d20b87, 0x0d7707d2, 0xfd26f341,2927		0xefeaf56f, 0x010f0c64, 0x110d0000,2928	}, {	// 6.1 MHz2929		0xffff0000, 0x00050012, 0x001c000b, 0xffd1ff84,2930		0xff66ffbe, 0x00960184, 0x01cd00da, 0xfeccfcb2,2931		0xfc17fdf9, 0x01e005bc, 0x06e703e4, 0xfdabf798,2932		0xf599f9b3, 0x02510abd, 0x0dbf08df, 0xfe48f3dc,2933		0xefd5f4f6, 0x00a20c3e, 0x110d0000,2934	}, {	// 6.2 MHz2935		0xfffffffe, 0x0002000f, 0x0021001f, 0xfff0ff97,2936		0xff50ff74, 0x0034014a, 0x01fa0179, 0xff97fd2a,2937		0xfbd3fcfa, 0x00a304fe, 0x07310525, 0xff37f886,2938		0xf55cf86e, 0x00c709d0, 0x0de209db, 0xff6df484,2939		0xefcbf481, 0x00360c18, 0x110d0000,2940	}, {	// 6.3 MHz2941		0xfffffffd, 0xfffe000a, 0x0021002f, 0x0010ffb8,2942		0xff50ff3b, 0xffcc00f0, 0x01fa01fa, 0x0069fdd4,2943		0xfbd3fc26, 0xff5d0407, 0x07310638, 0x00c9f9a8,2944		0xf55cf74e, 0xff3908c3, 0x0de20ac3, 0x0093f537,2945		0xefcbf410, 0xffca0bf2, 0x110d0000,2946	}, {	// 6.4 MHz2947		0xfffffffd, 0xfffb0003, 0x001c0037, 0x002fffe2,2948		0xff66ff17, 0xff6a007e, 0x01cd0251, 0x0134fea5,2949		0xfc17fb8b, 0xfe2002e0, 0x06e70713, 0x0255faf5,2950		0xf599f658, 0xfdaf0799, 0x0dbf0b96, 0x01b8f5f5,2951		0xefd5f3a3, 0xff5e0bca, 0x110d0000,2952	}, {	// 6.5 MHz2953		0x0000fffd, 0xfff9fffb, 0x00120037, 0x00460010,2954		0xff8eff0f, 0xff180000, 0x01750276, 0x01e8ff8d,2955		0xfc99fb31, 0xfcfb0198, 0x065607ad, 0x03cefc64,2956		0xf614f592, 0xfc2e0656, 0x0d770c52, 0x02daf6bd,2957		0xefeaf33b, 0xfef10ba3, 0x110d0000,2958	}, {	// 6.6 MHz2959		0x0000fffe, 0xfff7fff5, 0x0005002f, 0x0054003c,2960		0xffc5ff22, 0xfedfff82, 0x00fc0267, 0x0276007e,2961		0xfd51fb1c, 0xfbfe003e, 0x05830802, 0x0529fdec,2962		0xf6c8f4fe, 0xfabd04ff, 0x0d0d0cf6, 0x03f8f78f,2963		0xf00af2d7, 0xfe850b7b, 0x110d0000,2964	}, {	// 6.7 MHz2965		0x0000ffff, 0xfff8fff0, 0xfff80020, 0x00560060,2966		0x0002ff4e, 0xfec4ff10, 0x006d0225, 0x02d50166,2967		0xfe35fb4e, 0xfb35fee1, 0x0477080e, 0x065bff82,2968		0xf7b1f4a0, 0xf9610397, 0x0c810d80, 0x0510f869,2969		0xf033f278, 0xfe1a0b52, 0x110d0000,2970	}, {	// 6.8 MHz2971		0x00010000, 0xfffaffee, 0xffec000c, 0x004c0078,2972		0x0040ff8e, 0xfecafeb6, 0xffd301b6, 0x02fc0235,2973		0xff36fbc5, 0xfaaafd90, 0x033e07d2, 0x075b011b,2974		0xf8cbf47a, 0xf81f0224, 0x0bd50def, 0x0621f94b,2975		0xf067f21e, 0xfdae0b29, 0x110d0000,2976	}, {	// 6.9 MHz2977		0x00010001, 0xfffdffef, 0xffe3fff6, 0x0037007f,2978		0x0075ffdc, 0xfef2fe7c, 0xff3d0122, 0x02ea02dd,2979		0x0044fc79, 0xfa65fc5d, 0x01e3074e, 0x082102ad,2980		0xfa0ff48c, 0xf6fe00a9, 0x0b0a0e43, 0x0729fa33,2981		0xf0a5f1c9, 0xfd430b00, 0x110d0000,2982	}, {	// 7.0 MHz2983		0x00010002, 0x0001fff3, 0xffdeffe2, 0x001b0076,2984		0x009c002d, 0xff35fe68, 0xfeba0076, 0x029f0352,2985		0x014dfd60, 0xfa69fb53, 0x00740688, 0x08a7042d,2986		0xfb75f4d6, 0xf600ff2d, 0x0a220e7a, 0x0827fb22,2987		0xf0edf17a, 0xfcd80ad6, 0x110d0000,2988	}, {	// 7.1 MHz2989		0x00000003, 0x0004fff9, 0xffe0ffd2, 0xfffb005e,2990		0x00b0007a, 0xff8ffe7c, 0xfe53ffc1, 0x0221038c,2991		0x0241fe6e, 0xfab6fa80, 0xff010587, 0x08e90590,2992		0xfcf5f556, 0xf52bfdb3, 0x09210e95, 0x0919fc15,2993		0xf13ff12f, 0xfc6e0aab, 0x110d0000,2994	}, {	// 7.2 MHz2995		0x00000003, 0x00070000, 0xffe6ffc9, 0xffdb0039,2996		0x00af00b8, 0xfff4feb6, 0xfe13ff10, 0x01790388,2997		0x0311ff92, 0xfb48f9ed, 0xfd980453, 0x08e306cd,2998		0xfe88f60a, 0xf482fc40, 0x08080e93, 0x09fdfd0c,2999		0xf19af0ea, 0xfc050a81, 0x110d0000,3000	}, {	// 7.3 MHz3001		0x00000002, 0x00080008, 0xfff0ffc9, 0xffc1000d,3002		0x009800e2, 0x005bff10, 0xfe00fe74, 0x00b50345,3003		0x03b000bc, 0xfc18f9a1, 0xfc4802f9, 0x089807dc,3004		0x0022f6f0, 0xf407fada, 0x06da0e74, 0x0ad3fe06,3005		0xf1fef0ab, 0xfb9c0a55, 0x110d0000,3006	}, {	// 7.4 MHz3007		0x00000001, 0x0008000e, 0xfffdffd0, 0xffafffdf,3008		0x006e00f2, 0x00b8ff82, 0xfe1bfdf8, 0xffe302c8,3009		0x041301dc, 0xfd1af99e, 0xfb1e0183, 0x080908b5,3010		0x01bcf801, 0xf3bdf985, 0x059a0e38, 0x0b99ff03,3011		0xf26cf071, 0xfb330a2a, 0x110d0000,3012	}, {	// 7.5 MHz3013		0xffff0000, 0x00070011, 0x000affdf, 0xffa9ffb5,3014		0x003700e6, 0x01010000, 0xfe62fda8, 0xff140219,3015		0x043502e1, 0xfe42f9e6, 0xfa270000, 0x073a0953,3016		0x034cf939, 0xf3a4f845, 0x044c0de1, 0x0c4f0000,3017		0xf2e2f03c, 0xfacc09fe, 0x110d0000,3018	}, {	// 7.6 MHz3019		0xffffffff, 0x00040012, 0x0016fff3, 0xffafff95,3020		0xfff900c0, 0x0130007e, 0xfecefd89, 0xfe560146,3021		0x041303bc, 0xff81fa76, 0xf96cfe7d, 0x063209b1,3022		0x04c9fa93, 0xf3bdf71e, 0x02f30d6e, 0x0cf200fd,3023		0xf361f00e, 0xfa6509d1, 0x110d0000,3024	}, {	// 7.7 MHz3025		0xfffffffe, 0x00010010, 0x001e0008, 0xffc1ff84,3026		0xffbc0084, 0x013e00f0, 0xff56fd9f, 0xfdb8005c,3027		0x03b00460, 0x00c7fb45, 0xf8f4fd07, 0x04fa09ce,3028		0x062afc07, 0xf407f614, 0x01920ce0, 0x0d8301fa,3029		0xf3e8efe5, 0xfa0009a4, 0x110d0000,3030	}, {	// 7.8 MHz3031		0x0000fffd, 0xfffd000b, 0x0022001d, 0xffdbff82,3032		0xff870039, 0x012a014a, 0xffedfde7, 0xfd47ff6b,3033		0x031104c6, 0x0202fc4c, 0xf8c6fbad, 0x039909a7,3034		0x0767fd8e, 0xf482f52b, 0x002d0c39, 0x0e0002f4,3035		0xf477efc2, 0xf99b0977, 0x110d0000,3036	}, {	// 7.9 MHz3037		0x0000fffd, 0xfffa0004, 0x0020002d, 0xfffbff91,3038		0xff61ffe8, 0x00f70184, 0x0086fe5c, 0xfd0bfe85,3039		0x024104e5, 0x0323fd7d, 0xf8e2fa79, 0x021d093f,3040		0x0879ff22, 0xf52bf465, 0xfec70b79, 0x0e6803eb,3041		0xf50defa5, 0xf937094a, 0x110d0000,3042	}, {	// 8.0 MHz3043		0x0000fffe, 0xfff8fffd, 0x00190036, 0x001bffaf,3044		0xff4fff99, 0x00aa0198, 0x0112fef3, 0xfd09fdb9,3045		0x014d04be, 0x041bfecc, 0xf947f978, 0x00900897,3046		0x095a00b9, 0xf600f3c5, 0xfd650aa3, 0x0ebc04de,3047		0xf5aaef8e, 0xf8d5091c, 0x110d0000,3048	}, {	// 8.1 MHz3049		0x0000ffff, 0xfff7fff6, 0x000e0038, 0x0037ffd7,3050		0xff52ff56, 0x004b0184, 0x0186ffa1, 0xfd40fd16,3051		0x00440452, 0x04de0029, 0xf9f2f8b2, 0xfefe07b5,3052		0x0a05024d, 0xf6fef34d, 0xfc0a09b8, 0x0efa05cd,3053		0xf64eef7d, 0xf87308ed, 0x110d0000,3054	}, {	// 8.2 MHz3055		0x00010000, 0xfff8fff0, 0x00000031, 0x004c0005,3056		0xff6aff27, 0xffe4014a, 0x01d70057, 0xfdacfca6,3057		0xff3603a7, 0x05610184, 0xfadbf82e, 0xfd74069f,3058		0x0a7503d6, 0xf81ff2ff, 0xfab808b9, 0x0f2306b5,3059		0xf6f9ef72, 0xf81308bf, 0x110d0000,3060	}, {	// 8.3 MHz3061		0x00010001, 0xfffbffee, 0xfff30022, 0x00560032,3062		0xff95ff10, 0xff8000f0, 0x01fe0106, 0xfe46fc71,3063		0xfe3502c7, 0x059e02ce, 0xfbf9f7f2, 0xfbff055b,3064		0x0aa9054c, 0xf961f2db, 0xf97507aa, 0x0f350797,3065		0xf7a9ef6d, 0xf7b40890, 0x110d0000,3066	}, {	// 8.4 MHz3067		0x00010002, 0xfffeffee, 0xffe8000f, 0x00540058,3068		0xffcdff14, 0xff29007e, 0x01f6019e, 0xff01fc7c,3069		0xfd5101bf, 0x059203f6, 0xfd41f7fe, 0xfaa903f3,3070		0x0a9e06a9, 0xfabdf2e2, 0xf842068b, 0x0f320871,3071		0xf85eef6e, 0xf7560860, 0x110d0000,3072	}, {	// 8.5 MHz3073		0x00000003, 0x0002fff2, 0xffe1fff9, 0x00460073,3074		0x000bff34, 0xfee90000, 0x01c10215, 0xffd0fcc5,3075		0xfc99009d, 0x053d04f1, 0xfea5f853, 0xf97d0270,3076		0x0a5607e4, 0xfc2ef314, 0xf723055f, 0x0f180943,3077		0xf919ef75, 0xf6fa0830, 0x110d0000,3078	}, {	// 8.6 MHz3079		0x00000003, 0x0005fff8, 0xffdeffe4, 0x002f007f,3080		0x0048ff6b, 0xfec7ff82, 0x0163025f, 0x00a2fd47,3081		0xfc17ff73, 0x04a405b2, 0x0017f8ed, 0xf88500dc,3082		0x09d208f9, 0xfdaff370, 0xf61c0429, 0x0ee80a0b,3083		0xf9d8ef82, 0xf6a00800, 0x110d0000,3084	}, {	// 8.7 MHz3085		0x00000003, 0x0007ffff, 0xffe1ffd4, 0x0010007a,3086		0x007cffb2, 0xfec6ff10, 0x00e60277, 0x0168fdf9,3087		0xfbd3fe50, 0x03ce0631, 0x0188f9c8, 0xf7c7ff43,3088		0x091509e3, 0xff39f3f6, 0xf52d02ea, 0x0ea30ac9,3089		0xfa9bef95, 0xf64607d0, 0x110d0000,3090	}, {	// 8.8 MHz3091		0x00000002, 0x00090007, 0xffe9ffca, 0xfff00065,3092		0x00a10003, 0xfee6feb6, 0x0053025b, 0x0213fed0,3093		0xfbd3fd46, 0x02c70668, 0x02eafadb, 0xf74bfdae,3094		0x08230a9c, 0x00c7f4a3, 0xf45b01a6, 0x0e480b7c,3095		0xfb61efae, 0xf5ef079f, 0x110d0000,3096	}, {	// 8.9 MHz3097		0xffff0000, 0x0008000d, 0xfff5ffc8, 0xffd10043,3098		0x00b20053, 0xff24fe7c, 0xffb9020c, 0x0295ffbb,3099		0xfc17fc64, 0x019b0654, 0x042dfc1c, 0xf714fc2a,3100		0x07020b21, 0x0251f575, 0xf3a7005e, 0x0dd80c24,3101		0xfc2aefcd, 0xf599076e, 0x110d0000,3102	}, {	// 9.0 MHz3103		0xffffffff, 0x00060011, 0x0002ffcf, 0xffba0018,3104		0x00ad009a, 0xff79fe68, 0xff260192, 0x02e500ab,3105		0xfc99fbb6, 0x005b05f7, 0x0545fd81, 0xf723fabf,3106		0x05b80b70, 0x03d2f669, 0xf313ff15, 0x0d550cbf,3107		0xfcf6eff2, 0xf544073d, 0x110d0000,3108	}, {	// 9.1 MHz3109		0xfffffffe, 0x00030012, 0x000fffdd, 0xffacffea,3110		0x009300cf, 0xffdcfe7c, 0xfea600f7, 0x02fd0190,3111		0xfd51fb46, 0xff150554, 0x0627fefd, 0xf778f978,3112		0x044d0b87, 0x0543f77d, 0xf2a0fdcf, 0x0cbe0d4e,3113		0xfdc4f01d, 0xf4f2070b, 0x110d0000,3114	}, {	// 9.2 MHz3115		0x0000fffd, 0x00000010, 0x001afff0, 0xffaaffbf,3116		0x006700ed, 0x0043feb6, 0xfe460047, 0x02db0258,3117		0xfe35fb1b, 0xfddc0473, 0x06c90082, 0xf811f85e,3118		0x02c90b66, 0x069ff8ad, 0xf250fc8d, 0x0c140dcf,3119		0xfe93f04d, 0xf4a106d9, 0x110d0000,3120	}, {	// 9.3 MHz3121		0x0000fffd, 0xfffc000c, 0x00200006, 0xffb4ff9c,3122		0x002f00ef, 0x00a4ff10, 0xfe0dff92, 0x028102f7,3123		0xff36fb37, 0xfcbf035e, 0x07260202, 0xf8e8f778,3124		0x01340b0d, 0x07e1f9f4, 0xf223fb51, 0x0b590e42,3125		0xff64f083, 0xf45206a7, 0x110d0000,3126	}, {	// 9.4 MHz3127		0x0000fffd, 0xfff90005, 0x0022001a, 0xffc9ff86,3128		0xfff000d7, 0x00f2ff82, 0xfe01fee5, 0x01f60362,3129		0x0044fb99, 0xfbcc0222, 0x07380370, 0xf9f7f6cc,3130		0xff990a7e, 0x0902fb50, 0xf21afa1f, 0x0a8d0ea6,3131		0x0034f0bf, 0xf4050675, 0x110d0000,3132	}, {	// 9.5 MHz3133		0x0000fffe, 0xfff8fffe, 0x001e002b, 0xffe5ff81,3134		0xffb400a5, 0x01280000, 0xfe24fe50, 0x01460390,3135		0x014dfc3a, 0xfb1000ce, 0x070104bf, 0xfb37f65f,3136		0xfe0009bc, 0x0a00fcbb, 0xf235f8f8, 0x09b20efc,3137		0x0105f101, 0xf3ba0642, 0x110d0000,3138	}, {	// 9.6 MHz3139		0x0001ffff, 0xfff8fff7, 0x00150036, 0x0005ff8c,3140		0xff810061, 0x013d007e, 0xfe71fddf, 0x007c0380,3141		0x0241fd13, 0xfa94ff70, 0x068005e2, 0xfc9bf633,3142		0xfc7308ca, 0x0ad5fe30, 0xf274f7e0, 0x08c90f43,3143		0x01d4f147, 0xf371060f, 0x110d0000,3144	}, {	// 9.7 MHz3145		0x00010001, 0xfff9fff1, 0x00090038, 0x0025ffa7,3146		0xff5e0012, 0x013200f0, 0xfee3fd9b, 0xffaa0331,3147		0x0311fe15, 0xfa60fe18, 0x05bd06d1, 0xfe1bf64a,3148		0xfafa07ae, 0x0b7effab, 0xf2d5f6d7, 0x07d30f7a,3149		0x02a3f194, 0xf32905dc, 0x110d0000,3150	}, {	// 9.8 MHz3151		0x00010002, 0xfffcffee, 0xfffb0032, 0x003fffcd,3152		0xff4effc1, 0x0106014a, 0xff6efd8a, 0xfedd02aa,3153		0x03b0ff34, 0xfa74fcd7, 0x04bf0781, 0xffaaf6a3,3154		0xf99e066b, 0x0bf90128, 0xf359f5e1, 0x06d20fa2,3155		0x0370f1e5, 0xf2e405a8, 0x110d0000,3156	}, {	// 9.9 MHz3157		0x00000003, 0xffffffee, 0xffef0024, 0x0051fffa,3158		0xff54ff77, 0x00be0184, 0x0006fdad, 0xfe2701f3,3159		0x0413005e, 0xfad1fbba, 0x039007ee, 0x013bf73d,3160		0xf868050a, 0x0c4302a1, 0xf3fdf4fe, 0x05c70fba,3161		0x043bf23c, 0xf2a10575, 0x110d0000,3162	}, {	// 10.0 MHz3163		0x00000003, 0x0003fff1, 0xffe50011, 0x00570027,3164		0xff70ff3c, 0x00620198, 0x009efe01, 0xfd95011a,3165		0x04350183, 0xfb71fad0, 0x023c0812, 0x02c3f811,3166		0xf75e0390, 0x0c5c0411, 0xf4c1f432, 0x04b30fc1,3167		0x0503f297, 0xf2610541, 0x110d0000,3168	}, {	// 10.1 MHz3169		0x00000003, 0x0006fff7, 0xffdffffc, 0x00510050,3170		0xff9dff18, 0xfffc0184, 0x0128fe80, 0xfd32002e,3171		0x04130292, 0xfc4dfa21, 0x00d107ee, 0x0435f91c,3172		0xf6850205, 0x0c430573, 0xf5a1f37d, 0x03990fba,3173		0x05c7f2f8, 0xf222050d, 0x110d0000,3174	}, {	// 10.2 MHz3175		0x00000002, 0x0008fffe, 0xffdfffe7, 0x003f006e,3176		0xffd6ff0f, 0xff96014a, 0x0197ff1f, 0xfd05ff3e,3177		0x03b0037c, 0xfd59f9b7, 0xff5d0781, 0x0585fa56,3178		0xf5e4006f, 0x0bf906c4, 0xf69df2e0, 0x02790fa2,3179		0x0688f35d, 0xf1e604d8, 0x110d0000,3180	}, {	// 10.3 MHz3181		0xffff0001, 0x00090005, 0xffe4ffd6, 0x0025007e,3182		0x0014ff20, 0xff3c00f0, 0x01e1ffd0, 0xfd12fe5c,3183		0x03110433, 0xfe88f996, 0xfdf106d1, 0x06aafbb7,3184		0xf57efed8, 0x0b7e07ff, 0xf7b0f25e, 0x01560f7a,3185		0x0745f3c7, 0xf1ac04a4, 0x110d0000,3186	}, {	// 10.4 MHz3187		0xffffffff, 0x0008000c, 0xffedffcb, 0x0005007d,3188		0x0050ff4c, 0xfef6007e, 0x01ff0086, 0xfd58fd97,3189		0x024104ad, 0xffcaf9c0, 0xfc9905e2, 0x079afd35,3190		0xf555fd46, 0x0ad50920, 0xf8d9f1f6, 0x00310f43,3191		0x07fdf435, 0xf174046f, 0x110d0000,3192	}, {	// 10.5 MHz3193		0xfffffffe, 0x00050011, 0xfffaffc8, 0xffe5006b,3194		0x0082ff8c, 0xfecc0000, 0x01f00130, 0xfdd2fcfc,3195		0x014d04e3, 0x010efa32, 0xfb6404bf, 0x084efec5,3196		0xf569fbc2, 0x0a000a23, 0xfa15f1ab, 0xff0b0efc,3197		0x08b0f4a7, 0xf13f043a, 0x110d0000,3198	}, {	// 10.6 MHz3199		0x0000fffd, 0x00020012, 0x0007ffcd, 0xffc9004c,3200		0x00a4ffd9, 0xfec3ff82, 0x01b401c1, 0xfe76fc97,3201		0x004404d2, 0x0245fae8, 0xfa5f0370, 0x08c1005f,3202		0xf5bcfa52, 0x09020b04, 0xfb60f17b, 0xfde70ea6,3203		0x095df51e, 0xf10c0405, 0x110d0000,3204	}, {	// 10.7 MHz3205		0x0000fffd, 0xffff0011, 0x0014ffdb, 0xffb40023,3206		0x00b2002a, 0xfedbff10, 0x0150022d, 0xff38fc6f,3207		0xff36047b, 0x035efbda, 0xf9940202, 0x08ee01f5,3208		0xf649f8fe, 0x07e10bc2, 0xfcb6f169, 0xfcc60e42,3209		0x0a04f599, 0xf0db03d0, 0x110d0000,3210	}, {	// 10.8 MHz3211		0x0000fffd, 0xfffb000d, 0x001dffed, 0xffaafff5,3212		0x00aa0077, 0xff13feb6, 0x00ce026b, 0x000afc85,3213		0xfe3503e3, 0x044cfcfb, 0xf90c0082, 0x08d5037f,3214		0xf710f7cc, 0x069f0c59, 0xfe16f173, 0xfbaa0dcf,3215		0x0aa5f617, 0xf0ad039b, 0x110d0000,3216	}, {	// 10.9 MHz3217		0x0000fffe, 0xfff90006, 0x00210003, 0xffacffc8,3218		0x008e00b6, 0xff63fe7c, 0x003a0275, 0x00dafcda,3219		0xfd510313, 0x0501fe40, 0xf8cbfefd, 0x087604f0,3220		0xf80af6c2, 0x05430cc8, 0xff7af19a, 0xfa940d4e,3221		0x0b3ff699, 0xf0810365, 0x110d0000,3222	}, {	// 11.0 MHz3223		0x0001ffff, 0xfff8ffff, 0x00210018, 0xffbaffa3,3224		0x006000e1, 0xffc4fe68, 0xffa0024b, 0x019afd66,3225		0xfc990216, 0x0575ff99, 0xf8d4fd81, 0x07d40640,3226		0xf932f5e6, 0x03d20d0d, 0x00dff1de, 0xf9860cbf,3227		0x0bd1f71e, 0xf058032f, 0x110d0000,3228	}, {	// 11.1 MHz3229		0x00010000, 0xfff8fff8, 0x001b0029, 0xffd1ff8a,3230		0x002600f2, 0x002cfe7c, 0xff0f01f0, 0x023bfe20,3231		0xfc1700fa, 0x05a200f7, 0xf927fc1c, 0x06f40765,3232		0xfa82f53b, 0x02510d27, 0x0243f23d, 0xf8810c24,3233		0x0c5cf7a7, 0xf03102fa, 0x110d0000,3234	}, {	// 11.2 MHz3235		0x00010002, 0xfffafff2, 0x00110035, 0xfff0ff81,3236		0xffe700e7, 0x008ffeb6, 0xfe94016d, 0x02b0fefb,3237		0xfbd3ffd1, 0x05850249, 0xf9c1fadb, 0x05de0858,3238		0xfbf2f4c4, 0x00c70d17, 0x03a0f2b8, 0xf7870b7c,3239		0x0cdff833, 0xf00d02c4, 0x110d0000,3240	}, {	// 11.3 MHz3241		0x00000003, 0xfffdffee, 0x00040038, 0x0010ff88,3242		0xffac00c2, 0x00e2ff10, 0xfe3900cb, 0x02f1ffe9,3243		0xfbd3feaa, 0x05210381, 0xfa9cf9c8, 0x04990912,3244		0xfd7af484, 0xff390cdb, 0x04f4f34d, 0xf69a0ac9,3245		0x0d5af8c1, 0xefec028e, 0x110d0000,3246	}, {	// 11.4 MHz3247		0x00000003, 0x0000ffee, 0xfff60033, 0x002fff9f,3248		0xff7b0087, 0x011eff82, 0xfe080018, 0x02f900d8,3249		0xfc17fd96, 0x04790490, 0xfbadf8ed, 0x032f098e,3250		0xff10f47d, 0xfdaf0c75, 0x063cf3fc, 0xf5ba0a0b,3251		0x0dccf952, 0xefcd0258, 0x110d0000,3252	}, {	// 11.5 MHz3253		0x00000003, 0x0004fff1, 0xffea0026, 0x0046ffc3,3254		0xff5a003c, 0x013b0000, 0xfe04ff63, 0x02c801b8,3255		0xfc99fca6, 0x0397056a, 0xfcecf853, 0x01ad09c9,3256		0x00acf4ad, 0xfc2e0be7, 0x0773f4c2, 0xf4e90943,3257		0x0e35f9e6, 0xefb10221, 0x110d0000,3258	}, {	// 11.6 MHz3259		0x00000002, 0x0007fff6, 0xffe20014, 0x0054ffee,3260		0xff4effeb, 0x0137007e, 0xfe2efebb, 0x0260027a,3261		0xfd51fbe6, 0x02870605, 0xfe4af7fe, 0x001d09c1,3262		0x0243f515, 0xfabd0b32, 0x0897f59e, 0xf4280871,3263		0x0e95fa7c, 0xef9701eb, 0x110d0000,3264	}, {	// 11.7 MHz3265		0xffff0001, 0x0008fffd, 0xffdeffff, 0x0056001d,3266		0xff57ff9c, 0x011300f0, 0xfe82fe2e, 0x01ca0310,3267		0xfe35fb62, 0x0155065a, 0xffbaf7f2, 0xfe8c0977,3268		0x03cef5b2, 0xf9610a58, 0x09a5f68f, 0xf3790797,3269		0x0eebfb14, 0xef8001b5, 0x110d0000,3270	}, {	// 11.8 MHz3271		0xffff0000, 0x00080004, 0xffe0ffe9, 0x004c0047,3272		0xff75ff58, 0x00d1014a, 0xfef9fdc8, 0x0111036f,3273		0xff36fb21, 0x00120665, 0x012df82e, 0xfd0708ec,3274		0x0542f682, 0xf81f095c, 0x0a9af792, 0xf2db06b5,3275		0x0f38fbad, 0xef6c017e, 0x110d0000,3276	}, {	// 11.9 MHz3277		0xffffffff, 0x0007000b, 0xffe7ffd8, 0x00370068,3278		0xffa4ff28, 0x00790184, 0xff87fd91, 0x00430392,3279		0x0044fb26, 0xfece0626, 0x0294f8b2, 0xfb990825,3280		0x0698f77f, 0xf6fe0842, 0x0b73f8a7, 0xf25105cd,3281		0x0f7bfc48, 0xef5a0148, 0x110d0000,3282	}, {	// 12.0 MHz3283		0x0000fffe, 0x00050010, 0xfff2ffcc, 0x001b007b,3284		0xffdfff10, 0x00140198, 0x0020fd8e, 0xff710375,3285		0x014dfb73, 0xfd9a059f, 0x03e0f978, 0xfa4e0726,3286		0x07c8f8a7, 0xf600070c, 0x0c2ff9c9, 0xf1db04de,3287		0x0fb4fce5, 0xef4b0111, 0x110d0000,3288	}, {	// 12.1 MHz3289		0x0000fffd, 0x00010012, 0xffffffc8, 0xfffb007e,3290		0x001dff14, 0xffad0184, 0x00b7fdbe, 0xfea9031b,3291		0x0241fc01, 0xfc8504d6, 0x0504fa79, 0xf93005f6,3292		0x08caf9f2, 0xf52b05c0, 0x0ccbfaf9, 0xf17903eb,3293		0x0fe3fd83, 0xef3f00db, 0x110d0000,3294	}, {	// 12.2 MHz3295		0x0000fffd, 0xfffe0011, 0x000cffcc, 0xffdb0071,3296		0x0058ff32, 0xff4f014a, 0x013cfe1f, 0xfdfb028a,3297		0x0311fcc9, 0xfb9d03d6, 0x05f4fbad, 0xf848049d,3298		0x0999fb5b, 0xf4820461, 0x0d46fc32, 0xf12d02f4,3299		0x1007fe21, 0xef3600a4, 0x110d0000,3300	}, {	// 12.3 MHz3301		0x0000fffe, 0xfffa000e, 0x0017ffd9, 0xffc10055,3302		0x0088ff68, 0xff0400f0, 0x01a6fea7, 0xfd7501cc,3303		0x03b0fdc0, 0xfaef02a8, 0x06a7fd07, 0xf79d0326,3304		0x0a31fcda, 0xf40702f3, 0x0d9ffd72, 0xf0f601fa,3305		0x1021fec0, 0xef2f006d, 0x110d0000,3306	}, {	// 12.4 MHz3307		0x0001ffff, 0xfff80007, 0x001fffeb, 0xffaf002d,3308		0x00a8ffb0, 0xfed3007e, 0x01e9ff4c, 0xfd2000ee,3309		0x0413fed8, 0xfa82015c, 0x0715fe7d, 0xf7340198,3310		0x0a8dfe69, 0xf3bd017c, 0x0dd5feb8, 0xf0d500fd,3311		0x1031ff60, 0xef2b0037, 0x110d0000,3312	}, {	// 12.5 MHz3313		0x00010000, 0xfff70000, 0x00220000, 0xffa90000,3314		0x00b30000, 0xfec20000, 0x02000000, 0xfd030000,3315		0x04350000, 0xfa5e0000, 0x073b0000, 0xf7110000,3316		0x0aac0000, 0xf3a40000, 0x0de70000, 0xf0c90000,3317		0x10360000, 0xef290000, 0x110d0000,3318	}, {	// 12.6 MHz3319		0x00010001, 0xfff8fff9, 0x001f0015, 0xffafffd3,3320		0x00a80050, 0xfed3ff82, 0x01e900b4, 0xfd20ff12,3321		0x04130128, 0xfa82fea4, 0x07150183, 0xf734fe68,3322		0x0a8d0197, 0xf3bdfe84, 0x0dd50148, 0xf0d5ff03,3323		0x103100a0, 0xef2bffc9, 0x110d0000,3324	}, {	// 12.7 MHz3325		0x00000002, 0xfffafff2, 0x00170027, 0xffc1ffab,3326		0x00880098, 0xff04ff10, 0x01a60159, 0xfd75fe34,3327		0x03b00240, 0xfaeffd58, 0x06a702f9, 0xf79dfcda,3328		0x0a310326, 0xf407fd0d, 0x0d9f028e, 0xf0f6fe06,3329		0x10210140, 0xef2fff93, 0x110d0000,3330	}, {	// 12.8 MHz3331		0x00000003, 0xfffeffef, 0x000c0034, 0xffdbff8f,3332		0x005800ce, 0xff4ffeb6, 0x013c01e1, 0xfdfbfd76,3333		0x03110337, 0xfb9dfc2a, 0x05f40453, 0xf848fb63,3334		0x099904a5, 0xf482fb9f, 0x0d4603ce, 0xf12dfd0c,3335		0x100701df, 0xef36ff5c, 0x110d0000,3336	}, {	// 12.9 MHz3337		0x00000003, 0x0001ffee, 0xffff0038, 0xfffbff82,3338		0x001d00ec, 0xffadfe7c, 0x00b70242, 0xfea9fce5,3339		0x024103ff, 0xfc85fb2a, 0x05040587, 0xf930fa0a,3340		0x08ca060e, 0xf52bfa40, 0x0ccb0507, 0xf179fc15,3341		0x0fe3027d, 0xef3fff25, 0x110d0000,3342	}, {	// 13.0 MHz3343		0x00000002, 0x0005fff0, 0xfff20034, 0x001bff85,3344		0xffdf00f0, 0x0014fe68, 0x00200272, 0xff71fc8b,3345		0x014d048d, 0xfd9afa61, 0x03e00688, 0xfa4ef8da,3346		0x07c80759, 0xf600f8f4, 0x0c2f0637, 0xf1dbfb22,3347		0x0fb4031b, 0xef4bfeef, 0x110d0000,3348	}, {	// 13.1 MHz3349		0xffff0001, 0x0007fff5, 0xffe70028, 0x0037ff98,3350		0xffa400d8, 0x0079fe7c, 0xff87026f, 0x0043fc6e,3351		0x004404da, 0xfecef9da, 0x0294074e, 0xfb99f7db,3352		0x06980881, 0xf6fef7be, 0x0b730759, 0xf251fa33,3353		0x0f7b03b8, 0xef5afeb8, 0x110d0000,3354	}, {	// 13.2 MHz3355		0xffff0000, 0x0008fffc, 0xffe00017, 0x004cffb9,3356		0xff7500a8, 0x00d1feb6, 0xfef90238, 0x0111fc91,3357		0xff3604df, 0x0012f99b, 0x012d07d2, 0xfd07f714,3358		0x0542097e, 0xf81ff6a4, 0x0a9a086e, 0xf2dbf94b,3359		0x0f380453, 0xef6cfe82, 0x110d0000,3360	}, {	// 13.3 MHz3361		0xffffffff, 0x00080003, 0xffde0001, 0x0056ffe3,3362		0xff570064, 0x0113ff10, 0xfe8201d2, 0x01cafcf0,3363		0xfe35049e, 0x0155f9a6, 0xffba080e, 0xfe8cf689,3364		0x03ce0a4e, 0xf961f5a8, 0x09a50971, 0xf379f869,3365		0x0eeb04ec, 0xef80fe4b, 0x110d0000,3366	}, {	// 13.4 MHz3367		0x0000fffe, 0x0007000a, 0xffe2ffec, 0x00540012,3368		0xff4e0015, 0x0137ff82, 0xfe2e0145, 0x0260fd86,3369		0xfd51041a, 0x0287f9fb, 0xfe4a0802, 0x001df63f,3370		0x02430aeb, 0xfabdf4ce, 0x08970a62, 0xf428f78f,3371		0x0e950584, 0xef97fe15, 0x110d0000,3372	}, {	// 13.5 MHz3373		0x0000fffd, 0x0004000f, 0xffeaffda, 0x0046003d,3374		0xff5affc4, 0x013b0000, 0xfe04009d, 0x02c8fe48,3375		0xfc99035a, 0x0397fa96, 0xfcec07ad, 0x01adf637,3376		0x00ac0b53, 0xfc2ef419, 0x07730b3e, 0xf4e9f6bd,3377		0x0e35061a, 0xefb1fddf, 0x110d0000,3378	}, {	// 13.6 MHz3379		0x0000fffd, 0x00000012, 0xfff6ffcd, 0x002f0061,3380		0xff7bff79, 0x011e007e, 0xfe08ffe8, 0x02f9ff28,3381		0xfc17026a, 0x0479fb70, 0xfbad0713, 0x032ff672,3382		0xff100b83, 0xfdaff38b, 0x063c0c04, 0xf5baf5f5,3383		0x0dcc06ae, 0xefcdfda8, 0x110d0000,3384	}, {	// 13.7 MHz3385		0x0000fffd, 0xfffd0012, 0x0004ffc8, 0x00100078,3386		0xffacff3e, 0x00e200f0, 0xfe39ff35, 0x02f10017,3387		0xfbd30156, 0x0521fc7f, 0xfa9c0638, 0x0499f6ee,3388		0xfd7a0b7c, 0xff39f325, 0x04f40cb3, 0xf69af537,3389		0x0d5a073f, 0xefecfd72, 0x110d0000,3390	}, {	// 13.8 MHz3391		0x0001fffe, 0xfffa000e, 0x0011ffcb, 0xfff0007f,3392		0xffe7ff19, 0x008f014a, 0xfe94fe93, 0x02b00105,3393		0xfbd3002f, 0x0585fdb7, 0xf9c10525, 0x05def7a8,3394		0xfbf20b3c, 0x00c7f2e9, 0x03a00d48, 0xf787f484,3395		0x0cdf07cd, 0xf00dfd3c, 0x110d0000,3396	}, {	// 13.9 MHz3397		0x00010000, 0xfff80008, 0x001bffd7, 0xffd10076,3398		0x0026ff0e, 0x002c0184, 0xff0ffe10, 0x023b01e0,3399		0xfc17ff06, 0x05a2ff09, 0xf92703e4, 0x06f4f89b,3400		0xfa820ac5, 0x0251f2d9, 0x02430dc3, 0xf881f3dc,3401		0x0c5c0859, 0xf031fd06, 0x110d0000,3402	}, {	// 14.0 MHz3403		0x00010001, 0xfff80001, 0x0021ffe8, 0xffba005d,3404		0x0060ff1f, 0xffc40198, 0xffa0fdb5, 0x019a029a,3405		0xfc99fdea, 0x05750067, 0xf8d4027f, 0x07d4f9c0,3406		0xf9320a1a, 0x03d2f2f3, 0x00df0e22, 0xf986f341,3407		0x0bd108e2, 0xf058fcd1, 0x110d0000,3408	}, {	// 14.1 MHz3409		0x00000002, 0xfff9fffa, 0x0021fffd, 0xffac0038,3410		0x008eff4a, 0xff630184, 0x003afd8b, 0x00da0326,3411		0xfd51fced, 0x050101c0, 0xf8cb0103, 0x0876fb10,3412		0xf80a093e, 0x0543f338, 0xff7a0e66, 0xfa94f2b2,3413		0x0b3f0967, 0xf081fc9b, 0x110d0000,3414	}, {	// 14.2 MHz3415		0x00000003, 0xfffbfff3, 0x001d0013, 0xffaa000b,3416		0x00aaff89, 0xff13014a, 0x00cefd95, 0x000a037b,3417		0xfe35fc1d, 0x044c0305, 0xf90cff7e, 0x08d5fc81,3418		0xf7100834, 0x069ff3a7, 0xfe160e8d, 0xfbaaf231,3419		0x0aa509e9, 0xf0adfc65, 0x110d0000,3420	}, {	// 14.3 MHz3421		0x00000003, 0xffffffef, 0x00140025, 0xffb4ffdd,3422		0x00b2ffd6, 0xfedb00f0, 0x0150fdd3, 0xff380391,3423		0xff36fb85, 0x035e0426, 0xf994fdfe, 0x08eefe0b,3424		0xf6490702, 0x07e1f43e, 0xfcb60e97, 0xfcc6f1be,3425		0x0a040a67, 0xf0dbfc30, 0x110d0000,3426	}, {	// 14.4 MHz3427		0x00000003, 0x0002ffee, 0x00070033, 0xffc9ffb4,3428		0x00a40027, 0xfec3007e, 0x01b4fe3f, 0xfe760369,3429		0x0044fb2e, 0x02450518, 0xfa5ffc90, 0x08c1ffa1,3430		0xf5bc05ae, 0x0902f4fc, 0xfb600e85, 0xfde7f15a,3431		0x095d0ae2, 0xf10cfbfb, 0x110d0000,3432	}, {	// 14.5 MHz3433		0xffff0002, 0x0005ffef, 0xfffa0038, 0xffe5ff95,3434		0x00820074, 0xfecc0000, 0x01f0fed0, 0xfdd20304,3435		0x014dfb1d, 0x010e05ce, 0xfb64fb41, 0x084e013b,3436		0xf569043e, 0x0a00f5dd, 0xfa150e55, 0xff0bf104,3437		0x08b00b59, 0xf13ffbc6, 0x110d0000,3438	}, {	// 14.6 MHz3439		0xffff0001, 0x0008fff4, 0xffed0035, 0x0005ff83,3440		0x005000b4, 0xfef6ff82, 0x01ffff7a, 0xfd580269,3441		0x0241fb53, 0xffca0640, 0xfc99fa1e, 0x079a02cb,3442		0xf55502ba, 0x0ad5f6e0, 0xf8d90e0a, 0x0031f0bd,3443		0x07fd0bcb, 0xf174fb91, 0x110d0000,3444	}, {	// 14.7 MHz3445		0xffffffff, 0x0009fffb, 0xffe4002a, 0x0025ff82,3446		0x001400e0, 0xff3cff10, 0x01e10030, 0xfd1201a4,3447		0x0311fbcd, 0xfe88066a, 0xfdf1f92f, 0x06aa0449,3448		0xf57e0128, 0x0b7ef801, 0xf7b00da2, 0x0156f086,3449		0x07450c39, 0xf1acfb5c, 0x110d0000,3450	}, {	// 14.8 MHz3451		0x0000fffe, 0x00080002, 0xffdf0019, 0x003fff92,3452		0xffd600f1, 0xff96feb6, 0x019700e1, 0xfd0500c2,3453		0x03b0fc84, 0xfd590649, 0xff5df87f, 0x058505aa,3454		0xf5e4ff91, 0x0bf9f93c, 0xf69d0d20, 0x0279f05e,3455		0x06880ca3, 0xf1e6fb28, 0x110d0000,3456	}, {	// 14.9 MHz3457		0x0000fffd, 0x00060009, 0xffdf0004, 0x0051ffb0,3458		0xff9d00e8, 0xfffcfe7c, 0x01280180, 0xfd32ffd2,3459		0x0413fd6e, 0xfc4d05df, 0x00d1f812, 0x043506e4,3460		0xf685fdfb, 0x0c43fa8d, 0xf5a10c83, 0x0399f046,3461		0x05c70d08, 0xf222faf3, 0x110d0000,3462	}, {	// 15.0 MHz3463		0x0000fffd, 0x0003000f, 0xffe5ffef, 0x0057ffd9,3464		0xff7000c4, 0x0062fe68, 0x009e01ff, 0xfd95fee6,3465		0x0435fe7d, 0xfb710530, 0x023cf7ee, 0x02c307ef,3466		0xf75efc70, 0x0c5cfbef, 0xf4c10bce, 0x04b3f03f,3467		0x05030d69, 0xf261fabf, 0x110d0000,3468	}, {	// 15.1 MHz3469		0x0000fffd, 0xffff0012, 0xffefffdc, 0x00510006,3470		0xff540089, 0x00befe7c, 0x00060253, 0xfe27fe0d,3471		0x0413ffa2, 0xfad10446, 0x0390f812, 0x013b08c3,3472		0xf868faf6, 0x0c43fd5f, 0xf3fd0b02, 0x05c7f046,3473		0x043b0dc4, 0xf2a1fa8b, 0x110d0000,3474	}, {	// 15.2 MHz3475		0x0001fffe, 0xfffc0012, 0xfffbffce, 0x003f0033,3476		0xff4e003f, 0x0106feb6, 0xff6e0276, 0xfeddfd56,3477		0x03b000cc, 0xfa740329, 0x04bff87f, 0xffaa095d,3478		0xf99ef995, 0x0bf9fed8, 0xf3590a1f, 0x06d2f05e,3479		0x03700e1b, 0xf2e4fa58, 0x110d0000,3480	}, {	// 15.3 MHz3481		0x0001ffff, 0xfff9000f, 0x0009ffc8, 0x00250059,3482		0xff5effee, 0x0132ff10, 0xfee30265, 0xffaafccf,3483		0x031101eb, 0xfa6001e8, 0x05bdf92f, 0xfe1b09b6,3484		0xfafaf852, 0x0b7e0055, 0xf2d50929, 0x07d3f086,3485		0x02a30e6c, 0xf329fa24, 0x110d0000,3486	}, {	// 15.4 MHz3487		0x00010001, 0xfff80009, 0x0015ffca, 0x00050074,3488		0xff81ff9f, 0x013dff82, 0xfe710221, 0x007cfc80,3489		0x024102ed, 0xfa940090, 0x0680fa1e, 0xfc9b09cd,3490		0xfc73f736, 0x0ad501d0, 0xf2740820, 0x08c9f0bd,3491		0x01d40eb9, 0xf371f9f1, 0x110d0000,3492	}, {	// 15.5 MHz3493		0x00000002, 0xfff80002, 0x001effd5, 0xffe5007f,3494		0xffb4ff5b, 0x01280000, 0xfe2401b0, 0x0146fc70,3495		0x014d03c6, 0xfb10ff32, 0x0701fb41, 0xfb3709a1,3496		0xfe00f644, 0x0a000345, 0xf2350708, 0x09b2f104,3497		0x01050eff, 0xf3baf9be, 0x110d0000,3498	}, {	// 15.6 MHz3499		0x00000003, 0xfff9fffb, 0x0022ffe6, 0xffc9007a,3500		0xfff0ff29, 0x00f2007e, 0xfe01011b, 0x01f6fc9e,3501		0x00440467, 0xfbccfdde, 0x0738fc90, 0xf9f70934,3502		0xff99f582, 0x090204b0, 0xf21a05e1, 0x0a8df15a,3503		0x00340f41, 0xf405f98b, 0x110d0000,3504	}, {	// 15.7 MHz3505		0x00000003, 0xfffcfff4, 0x0020fffa, 0xffb40064,3506		0x002fff11, 0x00a400f0, 0xfe0d006e, 0x0281fd09,3507		0xff3604c9, 0xfcbffca2, 0x0726fdfe, 0xf8e80888,3508		0x0134f4f3, 0x07e1060c, 0xf22304af, 0x0b59f1be,3509		0xff640f7d, 0xf452f959, 0x110d0000,3510	}, {	// 15.8 MHz3511		0x00000003, 0x0000fff0, 0x001a0010, 0xffaa0041,3512		0x0067ff13, 0x0043014a, 0xfe46ffb9, 0x02dbfda8,3513		0xfe3504e5, 0xfddcfb8d, 0x06c9ff7e, 0xf81107a2,3514		0x02c9f49a, 0x069f0753, 0xf2500373, 0x0c14f231,3515		0xfe930fb3, 0xf4a1f927, 0x110d0000,3516	}, {	// 15.9 MHz3517		0xffff0002, 0x0003ffee, 0x000f0023, 0xffac0016,3518		0x0093ff31, 0xffdc0184, 0xfea6ff09, 0x02fdfe70,3519		0xfd5104ba, 0xff15faac, 0x06270103, 0xf7780688,3520		0x044df479, 0x05430883, 0xf2a00231, 0x0cbef2b2,3521		0xfdc40fe3, 0xf4f2f8f5, 0x110d0000,3522	}, {	// 16.0 MHz3523		0xffff0001, 0x0006ffef, 0x00020031, 0xffbaffe8,3524		0x00adff66, 0xff790198, 0xff26fe6e, 0x02e5ff55,3525		0xfc99044a, 0x005bfa09, 0x0545027f, 0xf7230541,3526		0x05b8f490, 0x03d20997, 0xf31300eb, 0x0d55f341,3527		0xfcf6100e, 0xf544f8c3, 0x110d0000,3528	}3529};3530 3531static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)3532{3533	u64 pll_freq;3534	u32 pll_freq_word;3535	const u32 *coeffs;3536 3537	v4l_dbg(1, cx25840_debug, client, "%s(%d)\n", __func__, ifHz);3538 3539	/* Assuming TV */3540	/* Calculate the PLL frequency word based on the adjusted ifHz */3541	pll_freq = div_u64((u64)ifHz * 268435456, 50000000);3542	pll_freq_word = (u32)pll_freq;3543 3544	cx25840_write4(client, DIF_PLL_FREQ_WORD,  pll_freq_word);3545 3546	/* Round down to the nearest 100KHz */3547	ifHz = (ifHz / 100000) * 100000;3548 3549	if (ifHz < 3000000)3550		ifHz = 3000000;3551 3552	if (ifHz > 16000000)3553		ifHz = 16000000;3554 3555	v4l_dbg(1, cx25840_debug, client, "%s(%d) again\n", __func__, ifHz);3556 3557	coeffs = ifhz_coeffs[(ifHz - 3000000) / 100000];3558	cx25840_write4(client, DIF_BPF_COEFF01, coeffs[0]);3559	cx25840_write4(client, DIF_BPF_COEFF23, coeffs[1]);3560	cx25840_write4(client, DIF_BPF_COEFF45, coeffs[2]);3561	cx25840_write4(client, DIF_BPF_COEFF67, coeffs[3]);3562	cx25840_write4(client, DIF_BPF_COEFF89, coeffs[4]);3563	cx25840_write4(client, DIF_BPF_COEFF1011, coeffs[5]);3564	cx25840_write4(client, DIF_BPF_COEFF1213, coeffs[6]);3565	cx25840_write4(client, DIF_BPF_COEFF1415, coeffs[7]);3566	cx25840_write4(client, DIF_BPF_COEFF1617, coeffs[8]);3567	cx25840_write4(client, DIF_BPF_COEFF1819, coeffs[9]);3568	cx25840_write4(client, DIF_BPF_COEFF2021, coeffs[10]);3569	cx25840_write4(client, DIF_BPF_COEFF2223, coeffs[11]);3570	cx25840_write4(client, DIF_BPF_COEFF2425, coeffs[12]);3571	cx25840_write4(client, DIF_BPF_COEFF2627, coeffs[13]);3572	cx25840_write4(client, DIF_BPF_COEFF2829, coeffs[14]);3573	cx25840_write4(client, DIF_BPF_COEFF3031, coeffs[15]);3574	cx25840_write4(client, DIF_BPF_COEFF3233, coeffs[16]);3575	cx25840_write4(client, DIF_BPF_COEFF3435, coeffs[17]);3576	cx25840_write4(client, DIF_BPF_COEFF36, coeffs[18]);3577}3578 3579static void cx23888_std_setup(struct i2c_client *client)3580{3581	struct cx25840_state *state = to_state(i2c_get_clientdata(client));3582	v4l2_std_id std = state->std;3583	u32 ifHz;3584 3585	cx25840_write4(client, 0x478, 0x6628021F);3586	cx25840_write4(client, 0x400, 0x0);3587	cx25840_write4(client, 0x4b4, 0x20524030);3588	cx25840_write4(client, 0x47c, 0x010a8263);3589 3590	if (std & V4L2_STD_525_60) {3591		v4l_dbg(1, cx25840_debug, client, "%s() Selecting NTSC",3592			__func__);3593 3594		/* Horiz / vert timing */3595		cx25840_write4(client, 0x428, 0x1e1e601a);3596		cx25840_write4(client, 0x424, 0x5b2d007a);3597 3598		/* DIF NTSC */3599		cx25840_write4(client, 0x304, 0x6503bc0c);3600		cx25840_write4(client, 0x308, 0xbd038c85);3601		cx25840_write4(client, 0x30c, 0x1db4640a);3602		cx25840_write4(client, 0x310, 0x00008800);3603		cx25840_write4(client, 0x314, 0x44400400);3604		cx25840_write4(client, 0x32c, 0x0c800800);3605		cx25840_write4(client, 0x330, 0x27000100);3606		cx25840_write4(client, 0x334, 0x1f296e1f);3607		cx25840_write4(client, 0x338, 0x009f50c1);3608		cx25840_write4(client, 0x340, 0x1befbf06);3609		cx25840_write4(client, 0x344, 0x000035e8);3610 3611		/* DIF I/F */3612		ifHz = 5400000;3613 3614	} else {3615		v4l_dbg(1, cx25840_debug, client, "%s() Selecting PAL-BG",3616			__func__);3617 3618		/* Horiz / vert timing */3619		cx25840_write4(client, 0x428, 0x28244024);3620		cx25840_write4(client, 0x424, 0x5d2d0084);3621 3622		/* DIF */3623		cx25840_write4(client, 0x304, 0x6503bc0c);3624		cx25840_write4(client, 0x308, 0xbd038c85);3625		cx25840_write4(client, 0x30c, 0x1db4640a);3626		cx25840_write4(client, 0x310, 0x00008800);3627		cx25840_write4(client, 0x314, 0x44400600);3628		cx25840_write4(client, 0x32c, 0x0c800800);3629		cx25840_write4(client, 0x330, 0x27000100);3630		cx25840_write4(client, 0x334, 0x213530ec);3631		cx25840_write4(client, 0x338, 0x00a65ba8);3632		cx25840_write4(client, 0x340, 0x1befbf06);3633		cx25840_write4(client, 0x344, 0x000035e8);3634 3635		/* DIF I/F */3636		ifHz = 6000000;3637	}3638 3639	cx23885_dif_setup(client, ifHz);3640 3641	/* Explicitly ensure the inputs are reconfigured after3642	 * a standard change.3643	 */3644	set_input(client, state->vid_input, state->aud_input);3645}3646 3647/* ----------------------------------------------------------------------- */3648 3649static const struct v4l2_ctrl_ops cx25840_ctrl_ops = {3650	.s_ctrl = cx25840_s_ctrl,3651};3652 3653static const struct v4l2_subdev_core_ops cx25840_core_ops = {3654	.log_status = cx25840_log_status,3655	.reset = cx25840_reset,3656	/* calling the (optional) init op will turn on the generic mode */3657	.init = cx25840_init,3658	.load_fw = cx25840_load_fw,3659	.s_io_pin_config = common_s_io_pin_config,3660#ifdef CONFIG_VIDEO_ADV_DEBUG3661	.g_register = cx25840_g_register,3662	.s_register = cx25840_s_register,3663#endif3664	.interrupt_service_routine = cx25840_irq_handler,3665};3666 3667static const struct v4l2_subdev_tuner_ops cx25840_tuner_ops = {3668	.s_frequency = cx25840_s_frequency,3669	.s_radio = cx25840_s_radio,3670	.g_tuner = cx25840_g_tuner,3671	.s_tuner = cx25840_s_tuner,3672};3673 3674static const struct v4l2_subdev_audio_ops cx25840_audio_ops = {3675	.s_clock_freq = cx25840_s_clock_freq,3676	.s_routing = cx25840_s_audio_routing,3677	.s_stream = cx25840_s_audio_stream,3678};3679 3680static const struct v4l2_subdev_video_ops cx25840_video_ops = {3681	.g_std = cx25840_g_std,3682	.s_std = cx25840_s_std,3683	.querystd = cx25840_querystd,3684	.s_routing = cx25840_s_video_routing,3685	.s_stream = cx25840_s_stream,3686	.g_input_status = cx25840_g_input_status,3687};3688 3689static const struct v4l2_subdev_vbi_ops cx25840_vbi_ops = {3690	.decode_vbi_line = cx25840_decode_vbi_line,3691	.s_raw_fmt = cx25840_s_raw_fmt,3692	.s_sliced_fmt = cx25840_s_sliced_fmt,3693	.g_sliced_fmt = cx25840_g_sliced_fmt,3694};3695 3696static const struct v4l2_subdev_pad_ops cx25840_pad_ops = {3697	.set_fmt = cx25840_set_fmt,3698};3699 3700static const struct v4l2_subdev_ops cx25840_ops = {3701	.core = &cx25840_core_ops,3702	.tuner = &cx25840_tuner_ops,3703	.audio = &cx25840_audio_ops,3704	.video = &cx25840_video_ops,3705	.vbi = &cx25840_vbi_ops,3706	.pad = &cx25840_pad_ops,3707	.ir = &cx25840_ir_ops,3708};3709 3710/* ----------------------------------------------------------------------- */3711 3712static u32 get_cx2388x_ident(struct i2c_client *client)3713{3714	u32 ret;3715 3716	/* Come out of digital power down */3717	cx25840_write(client, 0x000, 0);3718 3719	/*3720	 * Detecting whether the part is cx23885/7/8 is more3721	 * difficult than it needs to be. No ID register. Instead we3722	 * probe certain registers indicated in the datasheets to look3723	 * for specific defaults that differ between the silicon designs.3724	 */3725 3726	/* It's either 885/7 if the IR Tx Clk Divider register exists */3727	if (cx25840_read4(client, 0x204) & 0xffff) {3728		/*3729		 * CX23885 returns bogus repetitive byte values for the DIF,3730		 * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131)3731		 */3732		ret = cx25840_read4(client, 0x300);3733		if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) {3734			/* No DIF */3735			ret = CX23885_AV;3736		} else {3737			/*3738			 * CX23887 has a broken DIF, but the registers3739			 * appear valid (but unused), good enough to detect.3740			 */3741			ret = CX23887_AV;3742		}3743	} else if (cx25840_read4(client, 0x300) & 0x0fffffff) {3744		/* DIF PLL Freq Word reg exists; chip must be a CX23888 */3745		ret = CX23888_AV;3746	} else {3747		v4l_err(client, "Unable to detect h/w, assuming cx23887\n");3748		ret = CX23887_AV;3749	}3750 3751	/* Back into digital power down */3752	cx25840_write(client, 0x000, 2);3753	return ret;3754}3755 3756static int cx25840_probe(struct i2c_client *client)3757{3758	struct cx25840_state *state;3759	struct v4l2_subdev *sd;3760	int default_volume;3761	u32 id;3762	u16 device_id;3763#if defined(CONFIG_MEDIA_CONTROLLER)3764	int ret;3765#endif3766 3767	/* Check if the adapter supports the needed features */3768	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))3769		return -EIO;3770 3771	v4l_dbg(1, cx25840_debug, client,3772		"detecting cx25840 client on address 0x%x\n",3773		client->addr << 1);3774 3775	device_id = cx25840_read(client, 0x101) << 8;3776	device_id |= cx25840_read(client, 0x100);3777	v4l_dbg(1, cx25840_debug, client, "device_id = 0x%04x\n", device_id);3778 3779	/*3780	 * The high byte of the device ID should be3781	 * 0x83 for the cx2583x and 0x84 for the cx2584x3782	 */3783	if ((device_id & 0xff00) == 0x8300) {3784		id = CX25836 + ((device_id >> 4) & 0xf) - 6;3785	} else if ((device_id & 0xff00) == 0x8400) {3786		id = CX25840 + ((device_id >> 4) & 0xf);3787	} else if (device_id == 0x0000) {3788		id = get_cx2388x_ident(client);3789	} else if ((device_id & 0xfff0) == 0x5A30) {3790		/* The CX23100 (0x5A3C = 23100) doesn't have an A/V decoder */3791		id = CX2310X_AV;3792	} else if ((device_id & 0xff) == (device_id >> 8)) {3793		v4l_err(client,3794			"likely a confused/unresponsive cx2388[578] A/V decoder found @ 0x%x (%s)\n",3795			client->addr << 1, client->adapter->name);3796		v4l_err(client,3797			"A method to reset it from the cx25840 driver software is not known at this time\n");3798		return -ENODEV;3799	} else {3800		v4l_dbg(1, cx25840_debug, client, "cx25840 not found\n");3801		return -ENODEV;3802	}3803 3804	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);3805	if (!state)3806		return -ENOMEM;3807 3808	sd = &state->sd;3809	v4l2_i2c_subdev_init(sd, client, &cx25840_ops);3810#if defined(CONFIG_MEDIA_CONTROLLER)3811	/*3812	 * TODO: add media controller support for analog video inputs like3813	 * composite, svideo, etc.3814	 * A real input pad for this analog demod would be like:3815	 *                 ___________3816	 * TUNER --------> |         |3817	 *		   |         |3818	 * SVIDEO .......> | cx25840 |3819	 *		   |         |3820	 * COMPOSITE1 ...> |_________|3821	 *3822	 * However, at least for now, there's no much gain on modelling3823	 * those extra inputs. So, let's add it only when needed.3824	 */3825	state->pads[CX25840_PAD_INPUT].flags = MEDIA_PAD_FL_SINK;3826	state->pads[CX25840_PAD_INPUT].sig_type = PAD_SIGNAL_ANALOG;3827	state->pads[CX25840_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;3828	state->pads[CX25840_PAD_VID_OUT].sig_type = PAD_SIGNAL_DV;3829	sd->entity.function = MEDIA_ENT_F_ATV_DECODER;3830 3831	ret = media_entity_pads_init(&sd->entity, ARRAY_SIZE(state->pads),3832				     state->pads);3833	if (ret < 0) {3834		v4l_info(client, "failed to initialize media entity!\n");3835		return ret;3836	}3837#endif3838 3839	switch (id) {3840	case CX23885_AV:3841		v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",3842			 client->addr << 1, client->adapter->name);3843		break;3844	case CX23887_AV:3845		v4l_info(client, "cx23887 A/V decoder found @ 0x%x (%s)\n",3846			 client->addr << 1, client->adapter->name);3847		break;3848	case CX23888_AV:3849		v4l_info(client, "cx23888 A/V decoder found @ 0x%x (%s)\n",3850			 client->addr << 1, client->adapter->name);3851		break;3852	case CX2310X_AV:3853		v4l_info(client, "cx%d A/V decoder found @ 0x%x (%s)\n",3854			 device_id, client->addr << 1, client->adapter->name);3855		break;3856	case CX25840:3857	case CX25841:3858	case CX25842:3859	case CX25843:3860		/*3861		 * Note: revision '(device_id & 0x0f) == 2' was never built.3862		 * The marking skips from 0x1 == 22 to 0x3 == 23.3863		 */3864		v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n",3865			 (device_id & 0xfff0) >> 4,3866			 (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 13867						: (device_id & 0x0f),3868			 client->addr << 1, client->adapter->name);3869		break;3870	case CX25836:3871	case CX25837:3872	default:3873		v4l_info(client, "cx25%3x-%x found @ 0x%x (%s)\n",3874			 (device_id & 0xfff0) >> 4, device_id & 0x0f,3875			 client->addr << 1, client->adapter->name);3876		break;3877	}3878 3879	state->c = client;3880	state->vid_input = CX25840_COMPOSITE7;3881	state->aud_input = CX25840_AUDIO8;3882	state->audclk_freq = 48000;3883	state->audmode = V4L2_TUNER_MODE_LANG1;3884	state->vbi_line_offset = 8;3885	state->id = id;3886	state->rev = device_id;3887	state->vbi_regs_offset = id == CX23888_AV ? 0x500 - 0x424 : 0;3888	state->std = V4L2_STD_NTSC_M;3889	v4l2_ctrl_handler_init(&state->hdl, 9);3890	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,3891			  V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);3892	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,3893			  V4L2_CID_CONTRAST, 0, 127, 1, 64);3894	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,3895			  V4L2_CID_SATURATION, 0, 127, 1, 64);3896	v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,3897			  V4L2_CID_HUE, -128, 127, 1, 0);3898	if (!is_cx2583x(state)) {3899		default_volume = cx25840_read(client, 0x8d4);3900		/*3901		 * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume3902		 * scale mapping limits to avoid -ERANGE errors when3903		 * initializing the volume control3904		 */3905		if (default_volume > 228) {3906			/* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */3907			default_volume = 228;3908			cx25840_write(client, 0x8d4, 228);3909		} else if (default_volume < 20) {3910			/* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */3911			default_volume = 20;3912			cx25840_write(client, 0x8d4, 20);3913		}3914		default_volume = (((228 - default_volume) >> 1) + 23) << 9;3915 3916		state->volume = v4l2_ctrl_new_std(&state->hdl,3917						  &cx25840_audio_ctrl_ops,3918						  V4L2_CID_AUDIO_VOLUME,3919						  0, 65535, 65535 / 100,3920						  default_volume);3921		state->mute = v4l2_ctrl_new_std(&state->hdl,3922						&cx25840_audio_ctrl_ops,3923						V4L2_CID_AUDIO_MUTE,3924						0, 1, 1, 0);3925		v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,3926				  V4L2_CID_AUDIO_BALANCE,3927				  0, 65535, 65535 / 100, 32768);3928		v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,3929				  V4L2_CID_AUDIO_BASS,3930				  0, 65535, 65535 / 100, 32768);3931		v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,3932				  V4L2_CID_AUDIO_TREBLE,3933				  0, 65535, 65535 / 100, 32768);3934	}3935	sd->ctrl_handler = &state->hdl;3936	if (state->hdl.error) {3937		int err = state->hdl.error;3938 3939		v4l2_ctrl_handler_free(&state->hdl);3940		return err;3941	}3942	if (!is_cx2583x(state))3943		v4l2_ctrl_cluster(2, &state->volume);3944	v4l2_ctrl_handler_setup(&state->hdl);3945 3946	if (client->dev.platform_data) {3947		struct cx25840_platform_data *pdata = client->dev.platform_data;3948 3949		state->pvr150_workaround = pdata->pvr150_workaround;3950	}3951 3952	cx25840_ir_probe(sd);3953	return 0;3954}3955 3956static void cx25840_remove(struct i2c_client *client)3957{3958	struct v4l2_subdev *sd = i2c_get_clientdata(client);3959	struct cx25840_state *state = to_state(sd);3960 3961	cx25840_ir_remove(sd);3962	v4l2_device_unregister_subdev(sd);3963	v4l2_ctrl_handler_free(&state->hdl);3964}3965 3966static const struct i2c_device_id cx25840_id[] = {3967	{ "cx25840" },3968	{ }3969};3970MODULE_DEVICE_TABLE(i2c, cx25840_id);3971 3972static struct i2c_driver cx25840_driver = {3973	.driver = {3974		.name	= "cx25840",3975	},3976	.probe		= cx25840_probe,3977	.remove		= cx25840_remove,3978	.id_table	= cx25840_id,3979};3980 3981module_i2c_driver(cx25840_driver);3982