brintos

brintos / linux-shallow public Read only

0
0
Text · 17.4 KiB · 549b200 Raw
742 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Elonics E4000 silicon tuner driver4 *5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>6 */7 8#include "e4000_priv.h"9 10static int e4000_init(struct e4000_dev *dev)11{12	struct i2c_client *client = dev->client;13	int ret;14 15	dev_dbg(&client->dev, "\n");16 17	/* reset */18	ret = regmap_write(dev->regmap, 0x00, 0x01);19	if (ret)20		goto err;21 22	/* disable output clock */23	ret = regmap_write(dev->regmap, 0x06, 0x00);24	if (ret)25		goto err;26 27	ret = regmap_write(dev->regmap, 0x7a, 0x96);28	if (ret)29		goto err;30 31	/* configure gains */32	ret = regmap_bulk_write(dev->regmap, 0x7e, "\x01\xfe", 2);33	if (ret)34		goto err;35 36	ret = regmap_write(dev->regmap, 0x82, 0x00);37	if (ret)38		goto err;39 40	ret = regmap_write(dev->regmap, 0x24, 0x05);41	if (ret)42		goto err;43 44	ret = regmap_bulk_write(dev->regmap, 0x87, "\x20\x01", 2);45	if (ret)46		goto err;47 48	ret = regmap_bulk_write(dev->regmap, 0x9f, "\x7f\x07", 2);49	if (ret)50		goto err;51 52	/* DC offset control */53	ret = regmap_write(dev->regmap, 0x2d, 0x1f);54	if (ret)55		goto err;56 57	ret = regmap_bulk_write(dev->regmap, 0x70, "\x01\x01", 2);58	if (ret)59		goto err;60 61	/* gain control */62	ret = regmap_write(dev->regmap, 0x1a, 0x17);63	if (ret)64		goto err;65 66	ret = regmap_write(dev->regmap, 0x1f, 0x1a);67	if (ret)68		goto err;69 70	dev->active = true;71 72	return 0;73err:74	dev_dbg(&client->dev, "failed=%d\n", ret);75	return ret;76}77 78static int e4000_sleep(struct e4000_dev *dev)79{80	struct i2c_client *client = dev->client;81	int ret;82 83	dev_dbg(&client->dev, "\n");84 85	dev->active = false;86 87	ret = regmap_write(dev->regmap, 0x00, 0x00);88	if (ret)89		goto err;90 91	return 0;92err:93	dev_dbg(&client->dev, "failed=%d\n", ret);94	return ret;95}96 97static int e4000_set_params(struct e4000_dev *dev)98{99	struct i2c_client *client = dev->client;100	int ret, i;101	unsigned int div_n, k, k_cw, div_out;102	u64 f_vco;103	u8 buf[5], i_data[4], q_data[4];104 105	if (!dev->active) {106		dev_dbg(&client->dev, "tuner is sleeping\n");107		return 0;108	}109 110	/* gain control manual */111	ret = regmap_write(dev->regmap, 0x1a, 0x00);112	if (ret)113		goto err;114 115	/*116	 * Fractional-N synthesizer117	 *118	 *           +----------------------------+119	 *           v                            |120	 *  Fref   +----+     +-------+         +------+     +---+121	 * ------> | PD | --> |  VCO  | ------> | /N.F | <-- | K |122	 *         +----+     +-------+         +------+     +---+123	 *                      |124	 *                      |125	 *                      v126	 *                    +-------+  Fout127	 *                    | /Rout | ------>128	 *                    +-------+129	 */130	for (i = 0; i < ARRAY_SIZE(e4000_pll_lut); i++) {131		if (dev->f_frequency <= e4000_pll_lut[i].freq)132			break;133	}134	if (i == ARRAY_SIZE(e4000_pll_lut)) {135		ret = -EINVAL;136		goto err;137	}138 139	#define F_REF dev->clk140	div_out = e4000_pll_lut[i].div_out;141	f_vco = (u64) dev->f_frequency * div_out;142	/* calculate PLL integer and fractional control word */143	div_n = div_u64_rem(f_vco, F_REF, &k);144	k_cw = div_u64((u64) k * 0x10000, F_REF);145 146	dev_dbg(&client->dev,147		"frequency=%u bandwidth=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u\n",148		dev->f_frequency, dev->f_bandwidth, f_vco, F_REF, div_n, k,149		k_cw, div_out);150 151	buf[0] = div_n;152	buf[1] = (k_cw >> 0) & 0xff;153	buf[2] = (k_cw >> 8) & 0xff;154	buf[3] = 0x00;155	buf[4] = e4000_pll_lut[i].div_out_reg;156	ret = regmap_bulk_write(dev->regmap, 0x09, buf, 5);157	if (ret)158		goto err;159 160	/* LNA filter (RF filter) */161	for (i = 0; i < ARRAY_SIZE(e400_lna_filter_lut); i++) {162		if (dev->f_frequency <= e400_lna_filter_lut[i].freq)163			break;164	}165	if (i == ARRAY_SIZE(e400_lna_filter_lut)) {166		ret = -EINVAL;167		goto err;168	}169 170	ret = regmap_write(dev->regmap, 0x10, e400_lna_filter_lut[i].val);171	if (ret)172		goto err;173 174	/* IF filters */175	for (i = 0; i < ARRAY_SIZE(e4000_if_filter_lut); i++) {176		if (dev->f_bandwidth <= e4000_if_filter_lut[i].freq)177			break;178	}179	if (i == ARRAY_SIZE(e4000_if_filter_lut)) {180		ret = -EINVAL;181		goto err;182	}183 184	buf[0] = e4000_if_filter_lut[i].reg11_val;185	buf[1] = e4000_if_filter_lut[i].reg12_val;186 187	ret = regmap_bulk_write(dev->regmap, 0x11, buf, 2);188	if (ret)189		goto err;190 191	/* frequency band */192	for (i = 0; i < ARRAY_SIZE(e4000_band_lut); i++) {193		if (dev->f_frequency <= e4000_band_lut[i].freq)194			break;195	}196	if (i == ARRAY_SIZE(e4000_band_lut)) {197		ret = -EINVAL;198		goto err;199	}200 201	ret = regmap_write(dev->regmap, 0x07, e4000_band_lut[i].reg07_val);202	if (ret)203		goto err;204 205	ret = regmap_write(dev->regmap, 0x78, e4000_band_lut[i].reg78_val);206	if (ret)207		goto err;208 209	/* DC offset */210	for (i = 0; i < 4; i++) {211		if (i == 0)212			ret = regmap_bulk_write(dev->regmap, 0x15, "\x00\x7e\x24", 3);213		else if (i == 1)214			ret = regmap_bulk_write(dev->regmap, 0x15, "\x00\x7f", 2);215		else if (i == 2)216			ret = regmap_bulk_write(dev->regmap, 0x15, "\x01", 1);217		else218			ret = regmap_bulk_write(dev->regmap, 0x16, "\x7e", 1);219 220		if (ret)221			goto err;222 223		ret = regmap_write(dev->regmap, 0x29, 0x01);224		if (ret)225			goto err;226 227		ret = regmap_bulk_read(dev->regmap, 0x2a, buf, 3);228		if (ret)229			goto err;230 231		i_data[i] = (((buf[2] >> 0) & 0x3) << 6) | (buf[0] & 0x3f);232		q_data[i] = (((buf[2] >> 4) & 0x3) << 6) | (buf[1] & 0x3f);233	}234 235	swap(q_data[2], q_data[3]);236	swap(i_data[2], i_data[3]);237 238	ret = regmap_bulk_write(dev->regmap, 0x50, q_data, 4);239	if (ret)240		goto err;241 242	ret = regmap_bulk_write(dev->regmap, 0x60, i_data, 4);243	if (ret)244		goto err;245 246	/* gain control auto */247	ret = regmap_write(dev->regmap, 0x1a, 0x17);248	if (ret)249		goto err;250 251	return 0;252err:253	dev_dbg(&client->dev, "failed=%d\n", ret);254	return ret;255}256 257/*258 * V4L2 API259 */260#if IS_ENABLED(CONFIG_VIDEO_DEV)261static const struct v4l2_frequency_band bands[] = {262	{263		.type = V4L2_TUNER_RF,264		.index = 0,265		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,266		.rangelow   =    59000000,267		.rangehigh  =  1105000000,268	},269	{270		.type = V4L2_TUNER_RF,271		.index = 1,272		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,273		.rangelow   =  1249000000,274		.rangehigh  =  2208000000UL,275	},276};277 278static inline struct e4000_dev *e4000_subdev_to_dev(struct v4l2_subdev *sd)279{280	return container_of(sd, struct e4000_dev, sd);281}282 283static int e4000_standby(struct v4l2_subdev *sd)284{285	struct e4000_dev *dev = e4000_subdev_to_dev(sd);286	int ret;287 288	ret = e4000_sleep(dev);289	if (ret)290		return ret;291 292	return e4000_set_params(dev);293}294 295static int e4000_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)296{297	struct e4000_dev *dev = e4000_subdev_to_dev(sd);298	struct i2c_client *client = dev->client;299 300	dev_dbg(&client->dev, "index=%d\n", v->index);301 302	strscpy(v->name, "Elonics E4000", sizeof(v->name));303	v->type = V4L2_TUNER_RF;304	v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;305	v->rangelow  = bands[0].rangelow;306	v->rangehigh = bands[1].rangehigh;307	return 0;308}309 310static int e4000_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v)311{312	struct e4000_dev *dev = e4000_subdev_to_dev(sd);313	struct i2c_client *client = dev->client;314 315	dev_dbg(&client->dev, "index=%d\n", v->index);316	return 0;317}318 319static int e4000_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)320{321	struct e4000_dev *dev = e4000_subdev_to_dev(sd);322	struct i2c_client *client = dev->client;323 324	dev_dbg(&client->dev, "tuner=%d\n", f->tuner);325	f->frequency = dev->f_frequency;326	return 0;327}328 329static int e4000_s_frequency(struct v4l2_subdev *sd,330			      const struct v4l2_frequency *f)331{332	struct e4000_dev *dev = e4000_subdev_to_dev(sd);333	struct i2c_client *client = dev->client;334 335	dev_dbg(&client->dev, "tuner=%d type=%d frequency=%u\n",336		f->tuner, f->type, f->frequency);337 338	dev->f_frequency = clamp_t(unsigned int, f->frequency,339				   bands[0].rangelow, bands[1].rangehigh);340	return e4000_set_params(dev);341}342 343static int e4000_enum_freq_bands(struct v4l2_subdev *sd,344				  struct v4l2_frequency_band *band)345{346	struct e4000_dev *dev = e4000_subdev_to_dev(sd);347	struct i2c_client *client = dev->client;348 349	dev_dbg(&client->dev, "tuner=%d type=%d index=%d\n",350		band->tuner, band->type, band->index);351 352	if (band->index >= ARRAY_SIZE(bands))353		return -EINVAL;354 355	band->capability = bands[band->index].capability;356	band->rangelow = bands[band->index].rangelow;357	band->rangehigh = bands[band->index].rangehigh;358	return 0;359}360 361static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = {362	.standby                  = e4000_standby,363	.g_tuner                  = e4000_g_tuner,364	.s_tuner                  = e4000_s_tuner,365	.g_frequency              = e4000_g_frequency,366	.s_frequency              = e4000_s_frequency,367	.enum_freq_bands          = e4000_enum_freq_bands,368};369 370static const struct v4l2_subdev_ops e4000_subdev_ops = {371	.tuner                    = &e4000_subdev_tuner_ops,372};373 374static int e4000_set_lna_gain(struct dvb_frontend *fe)375{376	struct e4000_dev *dev = fe->tuner_priv;377	struct i2c_client *client = dev->client;378	int ret;379	u8 u8tmp;380 381	dev_dbg(&client->dev, "lna auto=%d->%d val=%d->%d\n",382		dev->lna_gain_auto->cur.val, dev->lna_gain_auto->val,383		dev->lna_gain->cur.val, dev->lna_gain->val);384 385	if (dev->lna_gain_auto->val && dev->if_gain_auto->cur.val)386		u8tmp = 0x17;387	else if (dev->lna_gain_auto->val)388		u8tmp = 0x19;389	else if (dev->if_gain_auto->cur.val)390		u8tmp = 0x16;391	else392		u8tmp = 0x10;393 394	ret = regmap_write(dev->regmap, 0x1a, u8tmp);395	if (ret)396		goto err;397 398	if (dev->lna_gain_auto->val == false) {399		ret = regmap_write(dev->regmap, 0x14, dev->lna_gain->val);400		if (ret)401			goto err;402	}403 404	return 0;405err:406	dev_dbg(&client->dev, "failed=%d\n", ret);407	return ret;408}409 410static int e4000_set_mixer_gain(struct dvb_frontend *fe)411{412	struct e4000_dev *dev = fe->tuner_priv;413	struct i2c_client *client = dev->client;414	int ret;415	u8 u8tmp;416 417	dev_dbg(&client->dev, "mixer auto=%d->%d val=%d->%d\n",418		dev->mixer_gain_auto->cur.val, dev->mixer_gain_auto->val,419		dev->mixer_gain->cur.val, dev->mixer_gain->val);420 421	if (dev->mixer_gain_auto->val)422		u8tmp = 0x15;423	else424		u8tmp = 0x14;425 426	ret = regmap_write(dev->regmap, 0x20, u8tmp);427	if (ret)428		goto err;429 430	if (dev->mixer_gain_auto->val == false) {431		ret = regmap_write(dev->regmap, 0x15, dev->mixer_gain->val);432		if (ret)433			goto err;434	}435 436	return 0;437err:438	dev_dbg(&client->dev, "failed=%d\n", ret);439	return ret;440}441 442static int e4000_set_if_gain(struct dvb_frontend *fe)443{444	struct e4000_dev *dev = fe->tuner_priv;445	struct i2c_client *client = dev->client;446	int ret;447	u8 buf[2];448	u8 u8tmp;449 450	dev_dbg(&client->dev, "if auto=%d->%d val=%d->%d\n",451		dev->if_gain_auto->cur.val, dev->if_gain_auto->val,452		dev->if_gain->cur.val, dev->if_gain->val);453 454	if (dev->if_gain_auto->val && dev->lna_gain_auto->cur.val)455		u8tmp = 0x17;456	else if (dev->lna_gain_auto->cur.val)457		u8tmp = 0x19;458	else if (dev->if_gain_auto->val)459		u8tmp = 0x16;460	else461		u8tmp = 0x10;462 463	ret = regmap_write(dev->regmap, 0x1a, u8tmp);464	if (ret)465		goto err;466 467	if (dev->if_gain_auto->val == false) {468		buf[0] = e4000_if_gain_lut[dev->if_gain->val].reg16_val;469		buf[1] = e4000_if_gain_lut[dev->if_gain->val].reg17_val;470		ret = regmap_bulk_write(dev->regmap, 0x16, buf, 2);471		if (ret)472			goto err;473	}474 475	return 0;476err:477	dev_dbg(&client->dev, "failed=%d\n", ret);478	return ret;479}480 481static int e4000_pll_lock(struct dvb_frontend *fe)482{483	struct e4000_dev *dev = fe->tuner_priv;484	struct i2c_client *client = dev->client;485	int ret;486	unsigned int uitmp;487 488	ret = regmap_read(dev->regmap, 0x07, &uitmp);489	if (ret)490		goto err;491 492	dev->pll_lock->val = (uitmp & 0x01);493 494	return 0;495err:496	dev_dbg(&client->dev, "failed=%d\n", ret);497	return ret;498}499 500static int e4000_g_volatile_ctrl(struct v4l2_ctrl *ctrl)501{502	struct e4000_dev *dev = container_of(ctrl->handler, struct e4000_dev, hdl);503	struct i2c_client *client = dev->client;504	int ret;505 506	if (!dev->active)507		return 0;508 509	switch (ctrl->id) {510	case  V4L2_CID_RF_TUNER_PLL_LOCK:511		ret = e4000_pll_lock(dev->fe);512		break;513	default:514		dev_dbg(&client->dev, "unknown ctrl: id=%d name=%s\n",515			ctrl->id, ctrl->name);516		ret = -EINVAL;517	}518 519	return ret;520}521 522static int e4000_s_ctrl(struct v4l2_ctrl *ctrl)523{524	struct e4000_dev *dev = container_of(ctrl->handler, struct e4000_dev, hdl);525	struct i2c_client *client = dev->client;526	int ret;527 528	if (!dev->active)529		return 0;530 531	switch (ctrl->id) {532	case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:533	case V4L2_CID_RF_TUNER_BANDWIDTH:534		/*535		 * TODO: Auto logic does not work 100% correctly as tuner driver536		 * do not have information to calculate maximum suitable537		 * bandwidth. Calculating it is responsible of master driver.538		 */539		dev->f_bandwidth = dev->bandwidth->val;540		ret = e4000_set_params(dev);541		break;542	case  V4L2_CID_RF_TUNER_LNA_GAIN_AUTO:543	case  V4L2_CID_RF_TUNER_LNA_GAIN:544		ret = e4000_set_lna_gain(dev->fe);545		break;546	case  V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO:547	case  V4L2_CID_RF_TUNER_MIXER_GAIN:548		ret = e4000_set_mixer_gain(dev->fe);549		break;550	case  V4L2_CID_RF_TUNER_IF_GAIN_AUTO:551	case  V4L2_CID_RF_TUNER_IF_GAIN:552		ret = e4000_set_if_gain(dev->fe);553		break;554	default:555		dev_dbg(&client->dev, "unknown ctrl: id=%d name=%s\n",556			ctrl->id, ctrl->name);557		ret = -EINVAL;558	}559 560	return ret;561}562 563static const struct v4l2_ctrl_ops e4000_ctrl_ops = {564	.g_volatile_ctrl = e4000_g_volatile_ctrl,565	.s_ctrl = e4000_s_ctrl,566};567#endif568 569/*570 * DVB API571 */572static int e4000_dvb_set_params(struct dvb_frontend *fe)573{574	struct e4000_dev *dev = fe->tuner_priv;575	struct dtv_frontend_properties *c = &fe->dtv_property_cache;576 577	dev->f_frequency = c->frequency;578	dev->f_bandwidth = c->bandwidth_hz;579	return e4000_set_params(dev);580}581 582static int e4000_dvb_init(struct dvb_frontend *fe)583{584	return e4000_init(fe->tuner_priv);585}586 587static int e4000_dvb_sleep(struct dvb_frontend *fe)588{589	return e4000_sleep(fe->tuner_priv);590}591 592static int e4000_dvb_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)593{594	*frequency = 0; /* Zero-IF */595	return 0;596}597 598static const struct dvb_tuner_ops e4000_dvb_tuner_ops = {599	.info = {600		.name              = "Elonics E4000",601		.frequency_min_hz  = 174 * MHz,602		.frequency_max_hz  = 862 * MHz,603	},604 605	.init = e4000_dvb_init,606	.sleep = e4000_dvb_sleep,607	.set_params = e4000_dvb_set_params,608 609	.get_if_frequency = e4000_dvb_get_if_frequency,610};611 612static int e4000_probe(struct i2c_client *client)613{614	struct e4000_dev *dev;615	struct e4000_config *cfg = client->dev.platform_data;616	struct dvb_frontend *fe = cfg->fe;617	int ret;618	unsigned int uitmp;619	static const struct regmap_config regmap_config = {620		.reg_bits = 8,621		.val_bits = 8,622	};623 624	dev = kzalloc(sizeof(*dev), GFP_KERNEL);625	if (!dev) {626		ret = -ENOMEM;627		goto err;628	}629 630	dev->clk = cfg->clock;631	dev->client = client;632	dev->fe = cfg->fe;633	dev->regmap = devm_regmap_init_i2c(client, &regmap_config);634	if (IS_ERR(dev->regmap)) {635		ret = PTR_ERR(dev->regmap);636		goto err_kfree;637	}638 639	/* check if the tuner is there */640	ret = regmap_read(dev->regmap, 0x02, &uitmp);641	if (ret)642		goto err_kfree;643 644	dev_dbg(&client->dev, "chip id=%02x\n", uitmp);645 646	if (uitmp != 0x40) {647		ret = -ENODEV;648		goto err_kfree;649	}650 651	/* put sleep as chip seems to be in normal mode by default */652	ret = regmap_write(dev->regmap, 0x00, 0x00);653	if (ret)654		goto err_kfree;655 656#if IS_ENABLED(CONFIG_VIDEO_DEV)657	/* Register controls */658	v4l2_ctrl_handler_init(&dev->hdl, 9);659	dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,660			V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);661	dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,662			V4L2_CID_RF_TUNER_BANDWIDTH, 4300000, 11000000, 100000, 4300000);663	v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false);664	dev->lna_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,665			V4L2_CID_RF_TUNER_LNA_GAIN_AUTO, 0, 1, 1, 1);666	dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,667			V4L2_CID_RF_TUNER_LNA_GAIN, 0, 15, 1, 10);668	v4l2_ctrl_auto_cluster(2, &dev->lna_gain_auto, 0, false);669	dev->mixer_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,670			V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO, 0, 1, 1, 1);671	dev->mixer_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,672			V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1);673	v4l2_ctrl_auto_cluster(2, &dev->mixer_gain_auto, 0, false);674	dev->if_gain_auto = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,675			V4L2_CID_RF_TUNER_IF_GAIN_AUTO, 0, 1, 1, 1);676	dev->if_gain = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,677			V4L2_CID_RF_TUNER_IF_GAIN, 0, 54, 1, 0);678	v4l2_ctrl_auto_cluster(2, &dev->if_gain_auto, 0, false);679	dev->pll_lock = v4l2_ctrl_new_std(&dev->hdl, &e4000_ctrl_ops,680			V4L2_CID_RF_TUNER_PLL_LOCK,  0, 1, 1, 0);681	if (dev->hdl.error) {682		ret = dev->hdl.error;683		dev_err(&client->dev, "Could not initialize controls\n");684		v4l2_ctrl_handler_free(&dev->hdl);685		goto err_kfree;686	}687 688	dev->sd.ctrl_handler = &dev->hdl;689	dev->f_frequency = bands[0].rangelow;690	dev->f_bandwidth = dev->bandwidth->val;691	v4l2_i2c_subdev_init(&dev->sd, client, &e4000_subdev_ops);692#endif693	fe->tuner_priv = dev;694	memcpy(&fe->ops.tuner_ops, &e4000_dvb_tuner_ops,695	       sizeof(fe->ops.tuner_ops));696	v4l2_set_subdevdata(&dev->sd, client);697	i2c_set_clientdata(client, &dev->sd);698 699	dev_info(&client->dev, "Elonics E4000 successfully identified\n");700	return 0;701err_kfree:702	kfree(dev);703err:704	dev_dbg(&client->dev, "failed=%d\n", ret);705	return ret;706}707 708static void e4000_remove(struct i2c_client *client)709{710	struct v4l2_subdev *sd = i2c_get_clientdata(client);711	struct e4000_dev *dev = container_of(sd, struct e4000_dev, sd);712 713	dev_dbg(&client->dev, "\n");714 715#if IS_ENABLED(CONFIG_VIDEO_DEV)716	v4l2_ctrl_handler_free(&dev->hdl);717#endif718	kfree(dev);719}720 721static const struct i2c_device_id e4000_id_table[] = {722	{ "e4000" },723	{}724};725MODULE_DEVICE_TABLE(i2c, e4000_id_table);726 727static struct i2c_driver e4000_driver = {728	.driver = {729		.name	= "e4000",730		.suppress_bind_attrs = true,731	},732	.probe		= e4000_probe,733	.remove		= e4000_remove,734	.id_table	= e4000_id_table,735};736 737module_i2c_driver(e4000_driver);738 739MODULE_DESCRIPTION("Elonics E4000 silicon tuner driver");740MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");741MODULE_LICENSE("GPL");742