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], ®map_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], ®map_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], ®map_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