brintos

brintos / linux-shallow public Read only

0
0
Text · 17.8 KiB · c3d8ced Raw
746 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Sony CXD2820R demodulator driver4 *5 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>6 */7 8 9#include "cxd2820r_priv.h"10 11/* Write register table */12int cxd2820r_wr_reg_val_mask_tab(struct cxd2820r_priv *priv,13				 const struct reg_val_mask *tab, int tab_len)14{15	struct i2c_client *client = priv->client[0];16	int ret;17	unsigned int i, reg, mask, val;18	struct regmap *regmap;19 20	dev_dbg(&client->dev, "tab_len=%d\n", tab_len);21 22	for (i = 0; i < tab_len; i++) {23		if ((tab[i].reg >> 16) & 0x1)24			regmap = priv->regmap[1];25		else26			regmap = priv->regmap[0];27 28		reg = (tab[i].reg >> 0) & 0xffff;29		val = tab[i].val;30		mask = tab[i].mask;31 32		if (mask == 0xff)33			ret = regmap_write(regmap, reg, val);34		else35			ret = regmap_write_bits(regmap, reg, mask, val);36		if (ret)37			goto error;38	}39 40	return 0;41error:42	dev_dbg(&client->dev, "failed=%d\n", ret);43	return ret;44}45 46int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio)47{48	struct cxd2820r_priv *priv = fe->demodulator_priv;49	struct i2c_client *client = priv->client[0];50	struct dtv_frontend_properties *c = &fe->dtv_property_cache;51	int ret, i;52	u8 tmp0, tmp1;53 54	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);55 56	/* update GPIOs only when needed */57	if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))58		return 0;59 60	tmp0 = 0x00;61	tmp1 = 0x00;62	for (i = 0; i < sizeof(priv->gpio); i++) {63		/* enable / disable */64		if (gpio[i] & CXD2820R_GPIO_E)65			tmp0 |= (2 << 6) >> (2 * i);66		else67			tmp0 |= (1 << 6) >> (2 * i);68 69		/* input / output */70		if (gpio[i] & CXD2820R_GPIO_I)71			tmp1 |= (1 << (3 + i));72		else73			tmp1 |= (0 << (3 + i));74 75		/* high / low */76		if (gpio[i] & CXD2820R_GPIO_H)77			tmp1 |= (1 << (0 + i));78		else79			tmp1 |= (0 << (0 + i));80 81		dev_dbg(&client->dev, "gpio i=%d %02x %02x\n", i, tmp0, tmp1);82	}83 84	dev_dbg(&client->dev, "wr gpio=%02x %02x\n", tmp0, tmp1);85 86	/* write bits [7:2] */87	ret = regmap_update_bits(priv->regmap[0], 0x0089, 0xfc, tmp0);88	if (ret)89		goto error;90 91	/* write bits [5:0] */92	ret = regmap_update_bits(priv->regmap[0], 0x008e, 0x3f, tmp1);93	if (ret)94		goto error;95 96	memcpy(priv->gpio, gpio, sizeof(priv->gpio));97 98	return ret;99error:100	dev_dbg(&client->dev, "failed=%d\n", ret);101	return ret;102}103 104static int cxd2820r_set_frontend(struct dvb_frontend *fe)105{106	struct cxd2820r_priv *priv = fe->demodulator_priv;107	struct i2c_client *client = priv->client[0];108	struct dtv_frontend_properties *c = &fe->dtv_property_cache;109	int ret;110 111	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);112 113	switch (c->delivery_system) {114	case SYS_DVBT:115		ret = cxd2820r_init_t(fe);116		if (ret < 0)117			goto err;118		ret = cxd2820r_set_frontend_t(fe);119		if (ret < 0)120			goto err;121		break;122	case SYS_DVBT2:123		ret = cxd2820r_init_t(fe);124		if (ret < 0)125			goto err;126		ret = cxd2820r_set_frontend_t2(fe);127		if (ret < 0)128			goto err;129		break;130	case SYS_DVBC_ANNEX_A:131		ret = cxd2820r_init_c(fe);132		if (ret < 0)133			goto err;134		ret = cxd2820r_set_frontend_c(fe);135		if (ret < 0)136			goto err;137		break;138	default:139		dev_dbg(&client->dev, "invalid delivery_system\n");140		ret = -EINVAL;141		break;142	}143err:144	return ret;145}146 147static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status)148{149	struct cxd2820r_priv *priv = fe->demodulator_priv;150	struct i2c_client *client = priv->client[0];151	struct dtv_frontend_properties *c = &fe->dtv_property_cache;152	int ret;153 154	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);155 156	switch (c->delivery_system) {157	case SYS_DVBT:158		ret = cxd2820r_read_status_t(fe, status);159		break;160	case SYS_DVBT2:161		ret = cxd2820r_read_status_t2(fe, status);162		break;163	case SYS_DVBC_ANNEX_A:164		ret = cxd2820r_read_status_c(fe, status);165		break;166	default:167		ret = -EINVAL;168		break;169	}170	return ret;171}172 173static int cxd2820r_get_frontend(struct dvb_frontend *fe,174				 struct dtv_frontend_properties *p)175{176	struct cxd2820r_priv *priv = fe->demodulator_priv;177	struct i2c_client *client = priv->client[0];178	struct dtv_frontend_properties *c = &fe->dtv_property_cache;179	int ret;180 181	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);182 183	if (priv->delivery_system == SYS_UNDEFINED)184		return 0;185 186	switch (c->delivery_system) {187	case SYS_DVBT:188		ret = cxd2820r_get_frontend_t(fe, p);189		break;190	case SYS_DVBT2:191		ret = cxd2820r_get_frontend_t2(fe, p);192		break;193	case SYS_DVBC_ANNEX_A:194		ret = cxd2820r_get_frontend_c(fe, p);195		break;196	default:197		ret = -EINVAL;198		break;199	}200	return ret;201}202 203static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)204{205	struct cxd2820r_priv *priv = fe->demodulator_priv;206	struct i2c_client *client = priv->client[0];207	struct dtv_frontend_properties *c = &fe->dtv_property_cache;208 209	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);210 211	*ber = (priv->post_bit_error - priv->post_bit_error_prev_dvbv3);212	priv->post_bit_error_prev_dvbv3 = priv->post_bit_error;213 214	return 0;215}216 217static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)218{219	struct cxd2820r_priv *priv = fe->demodulator_priv;220	struct i2c_client *client = priv->client[0];221	struct dtv_frontend_properties *c = &fe->dtv_property_cache;222 223	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);224 225	if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)226		*strength = c->strength.stat[0].uvalue;227	else228		*strength = 0;229 230	return 0;231}232 233static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)234{235	struct cxd2820r_priv *priv = fe->demodulator_priv;236	struct i2c_client *client = priv->client[0];237	struct dtv_frontend_properties *c = &fe->dtv_property_cache;238 239	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);240 241	if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)242		*snr = div_s64(c->cnr.stat[0].svalue, 100);243	else244		*snr = 0;245 246	return 0;247}248 249static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)250{251	struct cxd2820r_priv *priv = fe->demodulator_priv;252	struct i2c_client *client = priv->client[0];253	struct dtv_frontend_properties *c = &fe->dtv_property_cache;254 255	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);256 257	*ucblocks = 0;258 259	return 0;260}261 262static int cxd2820r_init(struct dvb_frontend *fe)263{264	return 0;265}266 267static int cxd2820r_sleep(struct dvb_frontend *fe)268{269	struct cxd2820r_priv *priv = fe->demodulator_priv;270	struct i2c_client *client = priv->client[0];271	struct dtv_frontend_properties *c = &fe->dtv_property_cache;272	int ret;273 274	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);275 276	switch (c->delivery_system) {277	case SYS_DVBT:278		ret = cxd2820r_sleep_t(fe);279		break;280	case SYS_DVBT2:281		ret = cxd2820r_sleep_t2(fe);282		break;283	case SYS_DVBC_ANNEX_A:284		ret = cxd2820r_sleep_c(fe);285		break;286	default:287		ret = -EINVAL;288		break;289	}290	return ret;291}292 293static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,294				      struct dvb_frontend_tune_settings *s)295{296	struct cxd2820r_priv *priv = fe->demodulator_priv;297	struct i2c_client *client = priv->client[0];298	struct dtv_frontend_properties *c = &fe->dtv_property_cache;299	int ret;300 301	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);302 303	switch (c->delivery_system) {304	case SYS_DVBT:305		ret = cxd2820r_get_tune_settings_t(fe, s);306		break;307	case SYS_DVBT2:308		ret = cxd2820r_get_tune_settings_t2(fe, s);309		break;310	case SYS_DVBC_ANNEX_A:311		ret = cxd2820r_get_tune_settings_c(fe, s);312		break;313	default:314		ret = -EINVAL;315		break;316	}317	return ret;318}319 320static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)321{322	struct cxd2820r_priv *priv = fe->demodulator_priv;323	struct i2c_client *client = priv->client[0];324	struct dtv_frontend_properties *c = &fe->dtv_property_cache;325	int ret, i;326	enum fe_status status = 0;327 328	dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system);329 330	/* switch between DVB-T and DVB-T2 when tune fails */331	if (priv->last_tune_failed) {332		if (priv->delivery_system == SYS_DVBT) {333			ret = cxd2820r_sleep_t(fe);334			if (ret)335				goto error;336 337			c->delivery_system = SYS_DVBT2;338		} else if (priv->delivery_system == SYS_DVBT2) {339			ret = cxd2820r_sleep_t2(fe);340			if (ret)341				goto error;342 343			c->delivery_system = SYS_DVBT;344		}345	}346 347	/* set frontend */348	ret = cxd2820r_set_frontend(fe);349	if (ret)350		goto error;351 352	/* frontend lock wait loop count */353	switch (priv->delivery_system) {354	case SYS_DVBT:355	case SYS_DVBC_ANNEX_A:356		i = 20;357		break;358	case SYS_DVBT2:359		i = 40;360		break;361	case SYS_UNDEFINED:362	default:363		i = 0;364		break;365	}366 367	/* wait frontend lock */368	for (; i > 0; i--) {369		dev_dbg(&client->dev, "loop=%d\n", i);370		msleep(50);371		ret = cxd2820r_read_status(fe, &status);372		if (ret)373			goto error;374 375		if (status & FE_HAS_LOCK)376			break;377	}378 379	/* check if we have a valid signal */380	if (status & FE_HAS_LOCK) {381		priv->last_tune_failed = false;382		return DVBFE_ALGO_SEARCH_SUCCESS;383	} else {384		priv->last_tune_failed = true;385		return DVBFE_ALGO_SEARCH_AGAIN;386	}387 388error:389	dev_dbg(&client->dev, "failed=%d\n", ret);390	return DVBFE_ALGO_SEARCH_ERROR;391}392 393static enum dvbfe_algo cxd2820r_get_frontend_algo(struct dvb_frontend *fe)394{395	return DVBFE_ALGO_CUSTOM;396}397 398static void cxd2820r_release(struct dvb_frontend *fe)399{400	struct cxd2820r_priv *priv = fe->demodulator_priv;401	struct i2c_client *client = priv->client[0];402 403	dev_dbg(&client->dev, "\n");404 405	i2c_unregister_device(client);406 407	return;408}409 410static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)411{412	struct cxd2820r_priv *priv = fe->demodulator_priv;413	struct i2c_client *client = priv->client[0];414 415	dev_dbg_ratelimited(&client->dev, "enable=%d\n", enable);416 417	return regmap_update_bits(priv->regmap[0], 0x00db, 0x01, enable ? 1 : 0);418}419 420#ifdef CONFIG_GPIOLIB421static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr,422		int val)423{424	struct cxd2820r_priv *priv = gpiochip_get_data(chip);425	struct i2c_client *client = priv->client[0];426	u8 gpio[GPIO_COUNT];427 428	dev_dbg(&client->dev, "nr=%u val=%d\n", nr, val);429 430	memcpy(gpio, priv->gpio, sizeof(gpio));431	gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2);432 433	return cxd2820r_gpio(&priv->fe, gpio);434}435 436static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val)437{438	struct cxd2820r_priv *priv = gpiochip_get_data(chip);439	struct i2c_client *client = priv->client[0];440	u8 gpio[GPIO_COUNT];441 442	dev_dbg(&client->dev, "nr=%u val=%d\n", nr, val);443 444	memcpy(gpio, priv->gpio, sizeof(gpio));445	gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2);446 447	(void) cxd2820r_gpio(&priv->fe, gpio);448 449	return;450}451 452static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr)453{454	struct cxd2820r_priv *priv = gpiochip_get_data(chip);455	struct i2c_client *client = priv->client[0];456 457	dev_dbg(&client->dev, "nr=%u\n", nr);458 459	return (priv->gpio[nr] >> 2) & 0x01;460}461#endif462 463static const struct dvb_frontend_ops cxd2820r_ops = {464	.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },465	/* default: DVB-T/T2 */466	.info = {467		.name = "Sony CXD2820R",468 469		.caps =	FE_CAN_FEC_1_2			|470			FE_CAN_FEC_2_3			|471			FE_CAN_FEC_3_4			|472			FE_CAN_FEC_5_6			|473			FE_CAN_FEC_7_8			|474			FE_CAN_FEC_AUTO			|475			FE_CAN_QPSK			|476			FE_CAN_QAM_16			|477			FE_CAN_QAM_32			|478			FE_CAN_QAM_64			|479			FE_CAN_QAM_128			|480			FE_CAN_QAM_256			|481			FE_CAN_QAM_AUTO			|482			FE_CAN_TRANSMISSION_MODE_AUTO	|483			FE_CAN_GUARD_INTERVAL_AUTO	|484			FE_CAN_HIERARCHY_AUTO		|485			FE_CAN_MUTE_TS			|486			FE_CAN_2G_MODULATION		|487			FE_CAN_MULTISTREAM488		},489 490	.release		= cxd2820r_release,491	.init			= cxd2820r_init,492	.sleep			= cxd2820r_sleep,493 494	.get_tune_settings	= cxd2820r_get_tune_settings,495	.i2c_gate_ctrl		= cxd2820r_i2c_gate_ctrl,496 497	.get_frontend		= cxd2820r_get_frontend,498 499	.get_frontend_algo	= cxd2820r_get_frontend_algo,500	.search			= cxd2820r_search,501 502	.read_status		= cxd2820r_read_status,503	.read_snr		= cxd2820r_read_snr,504	.read_ber		= cxd2820r_read_ber,505	.read_ucblocks		= cxd2820r_read_ucblocks,506	.read_signal_strength	= cxd2820r_read_signal_strength,507};508 509/*510 * XXX: That is wrapper to cxd2820r_probe() via driver core in order to provide511 * proper I2C client for legacy media attach binding.512 * New users must use I2C client binding directly!513 */514struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config,515				     struct i2c_adapter *adapter,516				     int *gpio_chip_base)517{518	struct i2c_client *client;519	struct i2c_board_info board_info;520	struct cxd2820r_platform_data pdata;521 522	pdata.ts_mode = config->ts_mode;523	pdata.ts_clk_inv = config->ts_clock_inv;524	pdata.if_agc_polarity = config->if_agc_polarity;525	pdata.spec_inv = config->spec_inv;526	pdata.gpio_chip_base = &gpio_chip_base;527	pdata.attach_in_use = true;528 529	memset(&board_info, 0, sizeof(board_info));530	strscpy(board_info.type, "cxd2820r", I2C_NAME_SIZE);531	board_info.addr = config->i2c_address;532	board_info.platform_data = &pdata;533	client = i2c_new_client_device(adapter, &board_info);534	if (!i2c_client_has_driver(client))535		return NULL;536 537	return pdata.get_dvb_frontend(client);538}539EXPORT_SYMBOL_GPL(cxd2820r_attach);540 541static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client)542{543	struct cxd2820r_priv *priv = i2c_get_clientdata(client);544 545	dev_dbg(&client->dev, "\n");546 547	return &priv->fe;548}549 550static int cxd2820r_probe(struct i2c_client *client)551{552	struct cxd2820r_platform_data *pdata = client->dev.platform_data;553	struct cxd2820r_priv *priv;554	int ret, *gpio_chip_base;555	unsigned int utmp;556	static const struct regmap_range_cfg regmap_range_cfg0[] = {557		{558			.range_min        = 0x0000,559			.range_max        = 0x3fff,560			.selector_reg     = 0x00,561			.selector_mask    = 0xff,562			.selector_shift   = 0,563			.window_start     = 0x00,564			.window_len       = 0x100,565		},566	};567	static const struct regmap_range_cfg regmap_range_cfg1[] = {568		{569			.range_min        = 0x0000,570			.range_max        = 0x01ff,571			.selector_reg     = 0x00,572			.selector_mask    = 0xff,573			.selector_shift   = 0,574			.window_start     = 0x00,575			.window_len       = 0x100,576		},577	};578	static const struct regmap_config regmap_config0 = {579		.reg_bits = 8,580		.val_bits = 8,581		.max_register = 0x3fff,582		.ranges = regmap_range_cfg0,583		.num_ranges = ARRAY_SIZE(regmap_range_cfg0),584		.cache_type = REGCACHE_NONE,585	};586	static const struct regmap_config regmap_config1 = {587		.reg_bits = 8,588		.val_bits = 8,589		.max_register = 0x01ff,590		.ranges = regmap_range_cfg1,591		.num_ranges = ARRAY_SIZE(regmap_range_cfg1),592		.cache_type = REGCACHE_NONE,593	};594 595	dev_dbg(&client->dev, "\n");596 597	priv = kzalloc(sizeof(*priv), GFP_KERNEL);598	if (!priv) {599		ret = -ENOMEM;600		goto err;601	}602 603	priv->client[0] = client;604	priv->fe.demodulator_priv = priv;605	priv->i2c = client->adapter;606	priv->ts_mode = pdata->ts_mode;607	priv->ts_clk_inv = pdata->ts_clk_inv;608	priv->if_agc_polarity = pdata->if_agc_polarity;609	priv->spec_inv = pdata->spec_inv;610	gpio_chip_base = *pdata->gpio_chip_base;611	priv->regmap[0] = regmap_init_i2c(priv->client[0], &regmap_config0);612	if (IS_ERR(priv->regmap[0])) {613		ret = PTR_ERR(priv->regmap[0]);614		goto err_kfree;615	}616 617	/* Check demod answers with correct chip id */618	ret = regmap_read(priv->regmap[0], 0x00fd, &utmp);619	if (ret)620		goto err_regmap_0_regmap_exit;621 622	dev_dbg(&client->dev, "chip_id=%02x\n", utmp);623 624	if (utmp != 0xe1) {625		ret = -ENODEV;626		goto err_regmap_0_regmap_exit;627	}628 629	/*630	 * Chip has two I2C addresses for different register banks. We register631	 * one dummy I2C client in order to get own I2C client for each632	 * register bank.633	 */634	priv->client[1] = i2c_new_dummy_device(client->adapter, client->addr | (1 << 1));635	if (IS_ERR(priv->client[1])) {636		ret = PTR_ERR(priv->client[1]);637		dev_err(&client->dev, "I2C registration failed\n");638		goto err_regmap_0_regmap_exit;639	}640 641	priv->regmap[1] = regmap_init_i2c(priv->client[1], &regmap_config1);642	if (IS_ERR(priv->regmap[1])) {643		ret = PTR_ERR(priv->regmap[1]);644		goto err_client_1_i2c_unregister_device;645	}646 647	if (gpio_chip_base) {648#ifdef CONFIG_GPIOLIB649		/* Add GPIOs */650		priv->gpio_chip.label = KBUILD_MODNAME;651		priv->gpio_chip.parent = &client->dev;652		priv->gpio_chip.owner = THIS_MODULE;653		priv->gpio_chip.direction_output = cxd2820r_gpio_direction_output;654		priv->gpio_chip.set = cxd2820r_gpio_set;655		priv->gpio_chip.get = cxd2820r_gpio_get;656		priv->gpio_chip.base = -1; /* Dynamic allocation */657		priv->gpio_chip.ngpio = GPIO_COUNT;658		priv->gpio_chip.can_sleep = 1;659		ret = gpiochip_add_data(&priv->gpio_chip, priv);660		if (ret)661			goto err_regmap_1_regmap_exit;662 663		dev_dbg(&client->dev, "gpio_chip.base=%d\n",664			priv->gpio_chip.base);665 666		*gpio_chip_base = priv->gpio_chip.base;667#else668		/*669		 * Use static GPIO configuration if GPIOLIB is undefined.670		 * This is fallback condition.671		 */672		u8 gpio[GPIO_COUNT];673		gpio[0] = (*gpio_chip_base >> 0) & 0x07;674		gpio[1] = (*gpio_chip_base >> 3) & 0x07;675		gpio[2] = 0;676		ret = cxd2820r_gpio(&priv->fe, gpio);677		if (ret)678			goto err_regmap_1_regmap_exit;679#endif680	}681 682	/* Create dvb frontend */683	memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops));684	if (!pdata->attach_in_use)685		priv->fe.ops.release = NULL;686	i2c_set_clientdata(client, priv);687 688	/* Setup callbacks */689	pdata->get_dvb_frontend = cxd2820r_get_dvb_frontend;690 691	dev_info(&client->dev, "Sony CXD2820R successfully identified\n");692 693	return 0;694err_regmap_1_regmap_exit:695	regmap_exit(priv->regmap[1]);696err_client_1_i2c_unregister_device:697	i2c_unregister_device(priv->client[1]);698err_regmap_0_regmap_exit:699	regmap_exit(priv->regmap[0]);700err_kfree:701	kfree(priv);702err:703	dev_dbg(&client->dev, "failed=%d\n", ret);704	return ret;705}706 707static void cxd2820r_remove(struct i2c_client *client)708{709	struct cxd2820r_priv *priv = i2c_get_clientdata(client);710 711	dev_dbg(&client->dev, "\n");712 713#ifdef CONFIG_GPIOLIB714	if (priv->gpio_chip.label)715		gpiochip_remove(&priv->gpio_chip);716#endif717	regmap_exit(priv->regmap[1]);718	i2c_unregister_device(priv->client[1]);719 720	regmap_exit(priv->regmap[0]);721 722	kfree(priv);723}724 725static const struct i2c_device_id cxd2820r_id_table[] = {726	{ "cxd2820r" },727	{}728};729MODULE_DEVICE_TABLE(i2c, cxd2820r_id_table);730 731static struct i2c_driver cxd2820r_driver = {732	.driver = {733		.name                = "cxd2820r",734		.suppress_bind_attrs = true,735	},736	.probe    = cxd2820r_probe,737	.remove   = cxd2820r_remove,738	.id_table = cxd2820r_id_table,739};740 741module_i2c_driver(cxd2820r_driver);742 743MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");744MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");745MODULE_LICENSE("GPL");746