brintos

brintos / linux-shallow public Read only

0
0
Text · 17.4 KiB · 7297516 Raw
732 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Panasonic MN88472 DVB-T/T2/C demodulator driver4 *5 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>6 */7 8#include "mn88472_priv.h"9 10static int mn88472_get_tune_settings(struct dvb_frontend *fe,11				     struct dvb_frontend_tune_settings *s)12{13	s->min_delay_ms = 1000;14	return 0;15}16 17static int mn88472_read_status(struct dvb_frontend *fe, enum fe_status *status)18{19	struct i2c_client *client = fe->demodulator_priv;20	struct mn88472_dev *dev = i2c_get_clientdata(client);21	struct dtv_frontend_properties *c = &fe->dtv_property_cache;22	int ret, i, stmp;23	unsigned int utmp, utmp1, utmp2;24	u8 buf[5];25 26	if (!dev->active) {27		ret = -EAGAIN;28		goto err;29	}30 31	switch (c->delivery_system) {32	case SYS_DVBT:33		ret = regmap_read(dev->regmap[0], 0x7f, &utmp);34		if (ret)35			goto err;36		if ((utmp & 0x0f) >= 0x09)37			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |38				  FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;39		else40			*status = 0;41		break;42	case SYS_DVBT2:43		ret = regmap_read(dev->regmap[2], 0x92, &utmp);44		if (ret)45			goto err;46		if ((utmp & 0x0f) >= 0x0d)47			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |48				  FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;49		else if ((utmp & 0x0f) >= 0x0a)50			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |51				  FE_HAS_VITERBI;52		else if ((utmp & 0x0f) >= 0x07)53			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;54		else55			*status = 0;56		break;57	case SYS_DVBC_ANNEX_A:58		ret = regmap_read(dev->regmap[1], 0x84, &utmp);59		if (ret)60			goto err;61		if ((utmp & 0x0f) >= 0x08)62			*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |63				  FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;64		else65			*status = 0;66		break;67	default:68		ret = -EINVAL;69		goto err;70	}71 72	/* Signal strength */73	if (*status & FE_HAS_SIGNAL) {74		for (i = 0; i < 2; i++) {75			ret = regmap_bulk_read(dev->regmap[2], 0x8e + i,76					       &buf[i], 1);77			if (ret)78				goto err;79		}80 81		utmp1 = buf[0] << 8 | buf[1] << 0 | buf[0] >> 2;82		dev_dbg(&client->dev, "strength=%u\n", utmp1);83 84		c->strength.stat[0].scale = FE_SCALE_RELATIVE;85		c->strength.stat[0].uvalue = utmp1;86	} else {87		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;88	}89 90	/* CNR */91	if (*status & FE_HAS_VITERBI && c->delivery_system == SYS_DVBT) {92		/* DVB-T CNR */93		ret = regmap_bulk_read(dev->regmap[0], 0x9c, buf, 2);94		if (ret)95			goto err;96 97		utmp = buf[0] << 8 | buf[1] << 0;98		if (utmp) {99			/* CNR[dB]: 10 * log10(65536 / value) + 2 */100			/* log10(65536) = 80807124, 0.2 = 3355443 */101			stmp = ((u64)80807124 - intlog10(utmp) + 3355443)102			       * 10000 >> 24;103 104			dev_dbg(&client->dev, "cnr=%d value=%u\n", stmp, utmp);105		} else {106			stmp = 0;107		}108 109		c->cnr.stat[0].svalue = stmp;110		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;111	} else if (*status & FE_HAS_VITERBI &&112		   c->delivery_system == SYS_DVBT2) {113		/* DVB-T2 CNR */114		for (i = 0; i < 3; i++) {115			ret = regmap_bulk_read(dev->regmap[2], 0xbc + i,116					       &buf[i], 1);117			if (ret)118				goto err;119		}120 121		utmp = buf[1] << 8 | buf[2] << 0;122		utmp1 = (buf[0] >> 2) & 0x01; /* 0=SISO, 1=MISO */123		if (utmp) {124			if (utmp1) {125				/* CNR[dB]: 10 * log10(16384 / value) - 6 */126				/* log10(16384) = 70706234, 0.6 = 10066330 */127				stmp = ((u64)70706234 - intlog10(utmp)128				       - 10066330) * 10000 >> 24;129				dev_dbg(&client->dev, "cnr=%d value=%u MISO\n",130					stmp, utmp);131			} else {132				/* CNR[dB]: 10 * log10(65536 / value) + 2 */133				/* log10(65536) = 80807124, 0.2 = 3355443 */134				stmp = ((u64)80807124 - intlog10(utmp)135				       + 3355443) * 10000 >> 24;136 137				dev_dbg(&client->dev, "cnr=%d value=%u SISO\n",138					stmp, utmp);139			}140		} else {141			stmp = 0;142		}143 144		c->cnr.stat[0].svalue = stmp;145		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;146	} else if (*status & FE_HAS_VITERBI &&147		   c->delivery_system == SYS_DVBC_ANNEX_A) {148		/* DVB-C CNR */149		ret = regmap_bulk_read(dev->regmap[1], 0xa1, buf, 4);150		if (ret)151			goto err;152 153		utmp1 = buf[0] << 8 | buf[1] << 0; /* signal */154		utmp2 = buf[2] << 8 | buf[3] << 0; /* noise */155		if (utmp1 && utmp2) {156			/* CNR[dB]: 10 * log10(8 * (signal / noise)) */157			/* log10(8) = 15151336 */158			stmp = ((u64)15151336 + intlog10(utmp1)159			       - intlog10(utmp2)) * 10000 >> 24;160 161			dev_dbg(&client->dev, "cnr=%d signal=%u noise=%u\n",162				stmp, utmp1, utmp2);163		} else {164			stmp = 0;165		}166 167		c->cnr.stat[0].svalue = stmp;168		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;169	} else {170		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;171	}172 173	/* PER */174	if (*status & FE_HAS_SYNC) {175		ret = regmap_bulk_read(dev->regmap[0], 0xe1, buf, 4);176		if (ret)177			goto err;178 179		utmp1 = buf[0] << 8 | buf[1] << 0;180		utmp2 = buf[2] << 8 | buf[3] << 0;181		dev_dbg(&client->dev, "block_error=%u block_count=%u\n",182			utmp1, utmp2);183 184		c->block_error.stat[0].scale = FE_SCALE_COUNTER;185		c->block_error.stat[0].uvalue += utmp1;186		c->block_count.stat[0].scale = FE_SCALE_COUNTER;187		c->block_count.stat[0].uvalue += utmp2;188	} else {189		c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;190		c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;191	}192 193	return 0;194err:195	dev_dbg(&client->dev, "failed=%d\n", ret);196	return ret;197}198 199static int mn88472_set_frontend(struct dvb_frontend *fe)200{201	struct i2c_client *client = fe->demodulator_priv;202	struct mn88472_dev *dev = i2c_get_clientdata(client);203	struct dtv_frontend_properties *c = &fe->dtv_property_cache;204	int ret, i;205	unsigned int utmp;206	u32 if_frequency;207	u8 buf[3], delivery_system_val, bandwidth_val, *bandwidth_vals_ptr;208	u8 reg_bank0_b4_val, reg_bank0_cd_val, reg_bank0_d4_val;209	u8 reg_bank0_d6_val;210 211	dev_dbg(&client->dev,212		"delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",213		c->delivery_system, c->modulation, c->frequency,214		c->bandwidth_hz, c->symbol_rate, c->inversion, c->stream_id);215 216	if (!dev->active) {217		ret = -EAGAIN;218		goto err;219	}220 221	switch (c->delivery_system) {222	case SYS_DVBT:223		delivery_system_val = 0x02;224		reg_bank0_b4_val = 0x00;225		reg_bank0_cd_val = 0x1f;226		reg_bank0_d4_val = 0x0a;227		reg_bank0_d6_val = 0x48;228		break;229	case SYS_DVBT2:230		delivery_system_val = 0x03;231		reg_bank0_b4_val = 0xf6;232		reg_bank0_cd_val = 0x01;233		reg_bank0_d4_val = 0x09;234		reg_bank0_d6_val = 0x46;235		break;236	case SYS_DVBC_ANNEX_A:237		delivery_system_val = 0x04;238		reg_bank0_b4_val = 0x00;239		reg_bank0_cd_val = 0x17;240		reg_bank0_d4_val = 0x09;241		reg_bank0_d6_val = 0x48;242		break;243	default:244		ret = -EINVAL;245		goto err;246	}247 248	switch (c->delivery_system) {249	case SYS_DVBT:250	case SYS_DVBT2:251		switch (c->bandwidth_hz) {252		case 5000000:253			bandwidth_vals_ptr = "\xe5\x99\x9a\x1b\xa9\x1b\xa9";254			bandwidth_val = 0x03;255			break;256		case 6000000:257			bandwidth_vals_ptr = "\xbf\x55\x55\x15\x6b\x15\x6b";258			bandwidth_val = 0x02;259			break;260		case 7000000:261			bandwidth_vals_ptr = "\xa4\x00\x00\x0f\x2c\x0f\x2c";262			bandwidth_val = 0x01;263			break;264		case 8000000:265			bandwidth_vals_ptr = "\x8f\x80\x00\x08\xee\x08\xee";266			bandwidth_val = 0x00;267			break;268		default:269			ret = -EINVAL;270			goto err;271		}272		break;273	case SYS_DVBC_ANNEX_A:274		bandwidth_vals_ptr = NULL;275		bandwidth_val = 0x00;276		break;277	default:278		break;279	}280 281	/* Program tuner */282	if (fe->ops.tuner_ops.set_params) {283		ret = fe->ops.tuner_ops.set_params(fe);284		if (ret)285			goto err;286	}287 288	if (fe->ops.tuner_ops.get_if_frequency) {289		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);290		if (ret)291			goto err;292 293		dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);294	} else {295		ret = -EINVAL;296		goto err;297	}298 299	ret = regmap_write(dev->regmap[2], 0x00, 0x66);300	if (ret)301		goto err;302	ret = regmap_write(dev->regmap[2], 0x01, 0x00);303	if (ret)304		goto err;305	ret = regmap_write(dev->regmap[2], 0x02, 0x01);306	if (ret)307		goto err;308	ret = regmap_write(dev->regmap[2], 0x03, delivery_system_val);309	if (ret)310		goto err;311	ret = regmap_write(dev->regmap[2], 0x04, bandwidth_val);312	if (ret)313		goto err;314 315	/* IF */316	utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, dev->clk);317	buf[0] = (utmp >> 16) & 0xff;318	buf[1] = (utmp >>  8) & 0xff;319	buf[2] = (utmp >>  0) & 0xff;320	for (i = 0; i < 3; i++) {321		ret = regmap_write(dev->regmap[2], 0x10 + i, buf[i]);322		if (ret)323			goto err;324	}325 326	/* Bandwidth */327	if (bandwidth_vals_ptr) {328		for (i = 0; i < 7; i++) {329			ret = regmap_write(dev->regmap[2], 0x13 + i,330					   bandwidth_vals_ptr[i]);331			if (ret)332				goto err;333		}334	}335 336	ret = regmap_write(dev->regmap[0], 0xb4, reg_bank0_b4_val);337	if (ret)338		goto err;339	ret = regmap_write(dev->regmap[0], 0xcd, reg_bank0_cd_val);340	if (ret)341		goto err;342	ret = regmap_write(dev->regmap[0], 0xd4, reg_bank0_d4_val);343	if (ret)344		goto err;345	ret = regmap_write(dev->regmap[0], 0xd6, reg_bank0_d6_val);346	if (ret)347		goto err;348 349	switch (c->delivery_system) {350	case SYS_DVBT:351		ret = regmap_write(dev->regmap[0], 0x07, 0x26);352		if (ret)353			goto err;354		ret = regmap_write(dev->regmap[0], 0x00, 0xba);355		if (ret)356			goto err;357		ret = regmap_write(dev->regmap[0], 0x01, 0x13);358		if (ret)359			goto err;360		break;361	case SYS_DVBT2:362		ret = regmap_write(dev->regmap[2], 0x2b, 0x13);363		if (ret)364			goto err;365		ret = regmap_write(dev->regmap[2], 0x4f, 0x05);366		if (ret)367			goto err;368		ret = regmap_write(dev->regmap[1], 0xf6, 0x05);369		if (ret)370			goto err;371		ret = regmap_write(dev->regmap[2], 0x32,372				(c->stream_id == NO_STREAM_ID_FILTER) ? 0 :373				c->stream_id );374		if (ret)375			goto err;376		break;377	case SYS_DVBC_ANNEX_A:378		break;379	default:380		break;381	}382 383	/* Reset FSM */384	ret = regmap_write(dev->regmap[2], 0xf8, 0x9f);385	if (ret)386		goto err;387 388	return 0;389err:390	dev_dbg(&client->dev, "failed=%d\n", ret);391	return ret;392}393 394static int mn88472_init(struct dvb_frontend *fe)395{396	struct i2c_client *client = fe->demodulator_priv;397	struct mn88472_dev *dev = i2c_get_clientdata(client);398	int ret, len, rem;399	unsigned int utmp;400	const struct firmware *firmware;401	const char *name = MN88472_FIRMWARE;402 403	dev_dbg(&client->dev, "\n");404 405	/* Power up */406	ret = regmap_write(dev->regmap[2], 0x05, 0x00);407	if (ret)408		goto err;409	ret = regmap_write(dev->regmap[2], 0x0b, 0x00);410	if (ret)411		goto err;412	ret = regmap_write(dev->regmap[2], 0x0c, 0x00);413	if (ret)414		goto err;415 416	/* Check if firmware is already running */417	ret = regmap_read(dev->regmap[0], 0xf5, &utmp);418	if (ret)419		goto err;420	if (!(utmp & 0x01))421		goto warm;422 423	ret = request_firmware(&firmware, name, &client->dev);424	if (ret) {425		dev_err(&client->dev, "firmware file '%s' not found\n", name);426		goto err;427	}428 429	dev_info(&client->dev, "downloading firmware from file '%s'\n", name);430 431	ret = regmap_write(dev->regmap[0], 0xf5, 0x03);432	if (ret)433		goto err_release_firmware;434 435	for (rem = firmware->size; rem > 0; rem -= (dev->i2c_write_max - 1)) {436		len = min(dev->i2c_write_max - 1, rem);437		ret = regmap_bulk_write(dev->regmap[0], 0xf6,438					&firmware->data[firmware->size - rem],439					len);440		if (ret) {441			dev_err(&client->dev, "firmware download failed %d\n",442				ret);443			goto err_release_firmware;444		}445	}446 447	/* Parity check of firmware */448	ret = regmap_read(dev->regmap[0], 0xf8, &utmp);449	if (ret)450		goto err_release_firmware;451	if (utmp & 0x10) {452		ret = -EINVAL;453		dev_err(&client->dev, "firmware did not run\n");454		goto err_release_firmware;455	}456 457	ret = regmap_write(dev->regmap[0], 0xf5, 0x00);458	if (ret)459		goto err_release_firmware;460 461	release_firmware(firmware);462warm:463	/* TS config */464	switch (dev->ts_mode) {465	case SERIAL_TS_MODE:466		utmp = 0x1d;467		break;468	case PARALLEL_TS_MODE:469		utmp = 0x00;470		break;471	default:472		ret = -EINVAL;473		goto err;474	}475	ret = regmap_write(dev->regmap[2], 0x08, utmp);476	if (ret)477		goto err;478 479	switch (dev->ts_clk) {480	case VARIABLE_TS_CLOCK:481		utmp = 0xe3;482		break;483	case FIXED_TS_CLOCK:484		utmp = 0xe1;485		break;486	default:487		ret = -EINVAL;488		goto err;489	}490	ret = regmap_write(dev->regmap[0], 0xd9, utmp);491	if (ret)492		goto err;493 494	dev->active = true;495 496	return 0;497err_release_firmware:498	release_firmware(firmware);499err:500	dev_dbg(&client->dev, "failed=%d\n", ret);501	return ret;502}503 504static int mn88472_sleep(struct dvb_frontend *fe)505{506	struct i2c_client *client = fe->demodulator_priv;507	struct mn88472_dev *dev = i2c_get_clientdata(client);508	int ret;509 510	dev_dbg(&client->dev, "\n");511 512	/* Power down */513	ret = regmap_write(dev->regmap[2], 0x0c, 0x30);514	if (ret)515		goto err;516	ret = regmap_write(dev->regmap[2], 0x0b, 0x30);517	if (ret)518		goto err;519	ret = regmap_write(dev->regmap[2], 0x05, 0x3e);520	if (ret)521		goto err;522 523	return 0;524err:525	dev_dbg(&client->dev, "failed=%d\n", ret);526	return ret;527}528 529static const struct dvb_frontend_ops mn88472_ops = {530	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},531	.info = {532		.name = "Panasonic MN88472",533		.symbol_rate_min = 1000000,534		.symbol_rate_max = 7200000,535		.caps =	FE_CAN_FEC_1_2                 |536			FE_CAN_FEC_2_3                 |537			FE_CAN_FEC_3_4                 |538			FE_CAN_FEC_5_6                 |539			FE_CAN_FEC_7_8                 |540			FE_CAN_FEC_AUTO                |541			FE_CAN_QPSK                    |542			FE_CAN_QAM_16                  |543			FE_CAN_QAM_32                  |544			FE_CAN_QAM_64                  |545			FE_CAN_QAM_128                 |546			FE_CAN_QAM_256                 |547			FE_CAN_QAM_AUTO                |548			FE_CAN_TRANSMISSION_MODE_AUTO  |549			FE_CAN_GUARD_INTERVAL_AUTO     |550			FE_CAN_HIERARCHY_AUTO          |551			FE_CAN_MUTE_TS                 |552			FE_CAN_2G_MODULATION           |553			FE_CAN_MULTISTREAM554	},555 556	.get_tune_settings = mn88472_get_tune_settings,557 558	.init = mn88472_init,559	.sleep = mn88472_sleep,560 561	.set_frontend = mn88472_set_frontend,562 563	.read_status = mn88472_read_status,564};565 566static struct dvb_frontend *mn88472_get_dvb_frontend(struct i2c_client *client)567{568	struct mn88472_dev *dev = i2c_get_clientdata(client);569 570	dev_dbg(&client->dev, "\n");571 572	return &dev->fe;573}574 575static int mn88472_probe(struct i2c_client *client)576{577	struct mn88472_config *pdata = client->dev.platform_data;578	struct mn88472_dev *dev;579	struct dtv_frontend_properties *c;580	int ret;581	unsigned int utmp;582	static const struct regmap_config regmap_config = {583		.reg_bits = 8,584		.val_bits = 8,585	};586 587	dev_dbg(&client->dev, "\n");588 589	dev = kzalloc(sizeof(*dev), GFP_KERNEL);590	if (!dev) {591		ret = -ENOMEM;592		goto err;593	}594 595	dev->i2c_write_max = pdata->i2c_wr_max ? pdata->i2c_wr_max : ~0;596	dev->clk = pdata->xtal;597	dev->ts_mode = pdata->ts_mode;598	dev->ts_clk = pdata->ts_clock;599	dev->client[0] = client;600	dev->regmap[0] = regmap_init_i2c(dev->client[0], &regmap_config);601	if (IS_ERR(dev->regmap[0])) {602		ret = PTR_ERR(dev->regmap[0]);603		goto err_kfree;604	}605 606	/*607	 * Chip has three I2C addresses for different register banks. Used608	 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,609	 * 0x1a and 0x1c, in order to get own I2C client for each register bank.610	 *611	 * Also, register bank 2 do not support sequential I/O. Only single612	 * register write or read is allowed to that bank.613	 */614	dev->client[1] = i2c_new_dummy_device(client->adapter, 0x1a);615	if (IS_ERR(dev->client[1])) {616		ret = PTR_ERR(dev->client[1]);617		dev_err(&client->dev, "I2C registration failed\n");618		goto err_regmap_0_regmap_exit;619	}620	dev->regmap[1] = regmap_init_i2c(dev->client[1], &regmap_config);621	if (IS_ERR(dev->regmap[1])) {622		ret = PTR_ERR(dev->regmap[1]);623		goto err_client_1_i2c_unregister_device;624	}625	i2c_set_clientdata(dev->client[1], dev);626 627	dev->client[2] = i2c_new_dummy_device(client->adapter, 0x1c);628	if (IS_ERR(dev->client[2])) {629		ret = PTR_ERR(dev->client[2]);630		dev_err(&client->dev, "2nd I2C registration failed\n");631		goto err_regmap_1_regmap_exit;632	}633	dev->regmap[2] = regmap_init_i2c(dev->client[2], &regmap_config);634	if (IS_ERR(dev->regmap[2])) {635		ret = PTR_ERR(dev->regmap[2]);636		goto err_client_2_i2c_unregister_device;637	}638	i2c_set_clientdata(dev->client[2], dev);639 640	/* Check demod answers with correct chip id */641	ret = regmap_read(dev->regmap[2], 0xff, &utmp);642	if (ret)643		goto err_regmap_2_regmap_exit;644 645	dev_dbg(&client->dev, "chip id=%02x\n", utmp);646 647	if (utmp != 0x02) {648		ret = -ENODEV;649		goto err_regmap_2_regmap_exit;650	}651 652	/* Sleep because chip is active by default */653	ret = regmap_write(dev->regmap[2], 0x05, 0x3e);654	if (ret)655		goto err_regmap_2_regmap_exit;656 657	/* Create dvb frontend */658	memcpy(&dev->fe.ops, &mn88472_ops, sizeof(struct dvb_frontend_ops));659	dev->fe.demodulator_priv = client;660	*pdata->fe = &dev->fe;661	i2c_set_clientdata(client, dev);662 663	/* Init stats to indicate which stats are supported */664	c = &dev->fe.dtv_property_cache;665	c->strength.len = 1;666	c->cnr.len = 1;667	c->block_error.len = 1;668	c->block_count.len = 1;669 670	/* Setup callbacks */671	pdata->get_dvb_frontend = mn88472_get_dvb_frontend;672 673	dev_info(&client->dev, "Panasonic MN88472 successfully identified\n");674 675	return 0;676err_regmap_2_regmap_exit:677	regmap_exit(dev->regmap[2]);678err_client_2_i2c_unregister_device:679	i2c_unregister_device(dev->client[2]);680err_regmap_1_regmap_exit:681	regmap_exit(dev->regmap[1]);682err_client_1_i2c_unregister_device:683	i2c_unregister_device(dev->client[1]);684err_regmap_0_regmap_exit:685	regmap_exit(dev->regmap[0]);686err_kfree:687	kfree(dev);688err:689	dev_dbg(&client->dev, "failed=%d\n", ret);690	return ret;691}692 693static void mn88472_remove(struct i2c_client *client)694{695	struct mn88472_dev *dev = i2c_get_clientdata(client);696 697	dev_dbg(&client->dev, "\n");698 699	regmap_exit(dev->regmap[2]);700	i2c_unregister_device(dev->client[2]);701 702	regmap_exit(dev->regmap[1]);703	i2c_unregister_device(dev->client[1]);704 705	regmap_exit(dev->regmap[0]);706 707	kfree(dev);708}709 710static const struct i2c_device_id mn88472_id_table[] = {711	{ "mn88472" },712	{}713};714MODULE_DEVICE_TABLE(i2c, mn88472_id_table);715 716static struct i2c_driver mn88472_driver = {717	.driver = {718		.name = "mn88472",719		.suppress_bind_attrs = true,720	},721	.probe    = mn88472_probe,722	.remove   = mn88472_remove,723	.id_table = mn88472_id_table,724};725 726module_i2c_driver(mn88472_driver);727 728MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");729MODULE_DESCRIPTION("Panasonic MN88472 DVB-T/T2/C demodulator driver");730MODULE_LICENSE("GPL");731MODULE_FIRMWARE(MN88472_FIRMWARE);732