brintos

brintos / linux-shallow public Read only

0
0
Text · 16.9 KiB · 53efdea Raw
782 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for the Techwell TW9900 multi-standard video decoder.4 *5 * Copyright (C) 2018 Fuzhou Rockchip Electronics Co., Ltd.6 * Copyright (C) 2020 Maxime Chevallier <maxime.chevallier@bootlin.com>7 * Copyright (C) 2023 Mehdi Djait <mehdi.djait@bootlin.com>8 */9 10#include <linux/bitfield.h>11#include <linux/clk.h>12#include <linux/delay.h>13#include <linux/device.h>14#include <linux/gpio/consumer.h>15#include <linux/i2c.h>16#include <linux/module.h>17#include <linux/pm_runtime.h>18#include <linux/regulator/consumer.h>19#include <media/media-entity.h>20#include <media/v4l2-async.h>21#include <media/v4l2-ctrls.h>22#include <media/v4l2-event.h>23#include <media/v4l2-subdev.h>24 25#define TW9900_REG_CHIP_ID			0x0026#define TW9900_REG_CHIP_STATUS			0x0127#define TW9900_REG_CHIP_STATUS_VDLOSS		BIT(7)28#define TW9900_REG_CHIP_STATUS_HLOCK		BIT(6)29#define TW9900_REG_OUT_FMT_CTL			0x0330#define TW9900_REG_OUT_FMT_CTL_STANDBY		0xA731#define TW9900_REG_OUT_FMT_CTL_STREAMING	0xA032#define TW9900_REG_CKHY_HSDLY			0x0433#define TW9900_REG_OUT_CTRL_I			0x0534#define TW9900_REG_ANALOG_CTL			0x0635#define TW9900_REG_CROP_HI			0x0736#define TW9900_REG_VDELAY_LO			0x0837#define TW9900_REG_VACTIVE_LO			0x0938#define TW9900_REG_HACTIVE_LO			0x0B39#define TW9900_REG_CNTRL1			0x0C40#define TW9900_REG_BRIGHT_CTL			0x1041#define TW9900_REG_CONTRAST_CTL			0x1142#define TW9900_REG_VBI_CNTL			0x1943#define TW9900_REG_ANAL_CTL_II			0x1A44#define TW9900_REG_OUT_CTRL_II			0x1B45#define TW9900_REG_STD				0x1C46#define TW9900_REG_STD_AUTO_PROGRESS		BIT(7)47#define TW9900_STDNOW_MASK			GENMASK(6, 4)48#define TW9900_REG_STDR				0x1D49#define TW9900_REG_MISSCNT			0x2650#define TW9900_REG_MISC_CTL_II			0x2F51#define TW9900_REG_VVBI				0x5552 53#define TW9900_CHIP_ID				0x0054#define TW9900_STD_NTSC_M			055#define TW9900_STD_PAL_BDGHI			156#define TW9900_STD_AUTO				757 58#define TW9900_VIDEO_POLL_TRIES			2059 60struct regval {61	u8 addr;62	u8 val;63};64 65struct tw9900_mode {66	u32 width;67	u32 height;68	u32 std;69	const struct regval *reg_list;70	int n_regs;71};72 73struct tw9900 {74	struct i2c_client *client;75	struct gpio_desc *reset_gpio;76	struct regulator *regulator;77 78	struct v4l2_subdev subdev;79	struct v4l2_ctrl_handler hdl;80	struct media_pad pad;81 82	/* Serialize access to hardware and global state. */83	struct mutex mutex;84 85	bool streaming;86	const struct tw9900_mode *cur_mode;87};88 89#define to_tw9900(sd) container_of(sd, struct tw9900, subdev)90 91static const struct regval tw9900_init_regs[] = {92	{ TW9900_REG_MISC_CTL_II,	0xE6 },93	{ TW9900_REG_MISSCNT,		0x24 },94	{ TW9900_REG_OUT_FMT_CTL,	0xA7 },95	{ TW9900_REG_ANAL_CTL_II,	0x0A },96	{ TW9900_REG_VDELAY_LO,		0x19 },97	{ TW9900_REG_STD,		0x00 },98	{ TW9900_REG_VACTIVE_LO,	0xF0 },99	{ TW9900_REG_STD,		0x07 },100	{ TW9900_REG_CKHY_HSDLY,	0x00 },101	{ TW9900_REG_ANALOG_CTL,	0x80 },102	{ TW9900_REG_CNTRL1,		0xDC },103	{ TW9900_REG_OUT_CTRL_I,	0x98 },104};105 106static const struct regval tw9900_pal_regs[] = {107	{ TW9900_REG_STD,		0x01 },108};109 110static const struct regval tw9900_ntsc_regs[] = {111	{ TW9900_REG_OUT_FMT_CTL,	0xA4 },112	{ TW9900_REG_VDELAY_LO,		0x12 },113	{ TW9900_REG_VACTIVE_LO,	0xF0 },114	{ TW9900_REG_CROP_HI,		0x02 },115	{ TW9900_REG_HACTIVE_LO,	0xD0 },116	{ TW9900_REG_VBI_CNTL,		0x01 },117	{ TW9900_REG_STD,		0x00 },118};119 120static const struct tw9900_mode supported_modes[] = {121	{122		.width = 720,123		.height = 480,124		.std = V4L2_STD_NTSC,125		.reg_list = tw9900_ntsc_regs,126		.n_regs = ARRAY_SIZE(tw9900_ntsc_regs),127	},128	{129		.width = 720,130		.height = 576,131		.std = V4L2_STD_PAL,132		.reg_list = tw9900_pal_regs,133		.n_regs = ARRAY_SIZE(tw9900_pal_regs),134	},135};136 137static int tw9900_write_reg(struct i2c_client *client, u8 reg, u8 val)138{139	int ret;140 141	ret = i2c_smbus_write_byte_data(client, reg, val);142	if (ret < 0)143		dev_err(&client->dev, "write reg error: %d\n", ret);144 145	return ret;146}147 148static int tw9900_write_array(struct i2c_client *client,149			      const struct regval *regs, int n_regs)150{151	int i, ret = 0;152 153	for (i = 0; i < n_regs; i++) {154		ret = tw9900_write_reg(client, regs[i].addr, regs[i].val);155		if (ret)156			return ret;157	}158 159	return 0;160}161 162static int tw9900_read_reg(struct i2c_client *client, u8 reg)163{164	int ret;165 166	ret = i2c_smbus_read_byte_data(client, reg);167	if (ret < 0)168		dev_err(&client->dev, "read reg error: %d\n", ret);169 170	return ret;171}172 173static void tw9900_fill_fmt(const struct tw9900_mode *mode,174			    struct v4l2_mbus_framefmt *fmt)175{176	fmt->code = MEDIA_BUS_FMT_UYVY8_2X8;177	fmt->width = mode->width;178	fmt->height = mode->height;179	fmt->field = V4L2_FIELD_NONE;180	fmt->quantization = V4L2_QUANTIZATION_DEFAULT;181	fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;182	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M);183	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M);184}185 186static int tw9900_get_fmt(struct v4l2_subdev *sd,187			  struct v4l2_subdev_state *sd_state,188			  struct v4l2_subdev_format *fmt)189{190	struct tw9900 *tw9900 = to_tw9900(sd);191	struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;192 193	mutex_lock(&tw9900->mutex);194	tw9900_fill_fmt(tw9900->cur_mode, mbus_fmt);195	mutex_unlock(&tw9900->mutex);196 197	return 0;198}199 200static int tw9900_set_fmt(struct v4l2_subdev *sd,201			  struct v4l2_subdev_state *sd_state,202			  struct v4l2_subdev_format *fmt)203{204	struct tw9900 *tw9900 = to_tw9900(sd);205	struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;206 207	mutex_lock(&tw9900->mutex);208 209	if (tw9900->streaming) {210		mutex_unlock(&tw9900->mutex);211		return -EBUSY;212	}213 214	tw9900_fill_fmt(tw9900->cur_mode, mbus_fmt);215 216	mutex_unlock(&tw9900->mutex);217 218	return 0;219}220 221static int tw9900_enum_mbus_code(struct v4l2_subdev *sd,222				 struct v4l2_subdev_state *sd_state,223				 struct v4l2_subdev_mbus_code_enum *code)224{225	if (code->index > 0)226		return -EINVAL;227 228	code->code = MEDIA_BUS_FMT_UYVY8_2X8;229 230	return 0;231}232 233static int tw9900_s_ctrl(struct v4l2_ctrl *ctrl)234{235	struct tw9900 *tw9900 = container_of(ctrl->handler, struct tw9900, hdl);236	int ret;237 238	if (pm_runtime_suspended(&tw9900->client->dev))239		return 0;240 241	/* v4l2_ctrl_lock() locks tw9900->mutex. */242	switch (ctrl->id) {243	case V4L2_CID_BRIGHTNESS:244		ret = tw9900_write_reg(tw9900->client, TW9900_REG_BRIGHT_CTL,245				       (u8)ctrl->val);246		break;247	case V4L2_CID_CONTRAST:248		ret = tw9900_write_reg(tw9900->client, TW9900_REG_CONTRAST_CTL,249				       (u8)ctrl->val);250		break;251	default:252		ret = -EINVAL;253		break;254	}255 256	return ret;257}258 259static int tw9900_s_stream(struct v4l2_subdev *sd, int on)260{261	struct tw9900 *tw9900 = to_tw9900(sd);262	struct i2c_client *client = tw9900->client;263	int ret;264 265	mutex_lock(&tw9900->mutex);266 267	if (tw9900->streaming == on) {268		mutex_unlock(&tw9900->mutex);269		return 0;270	}271 272	mutex_unlock(&tw9900->mutex);273 274	if (on) {275		ret = pm_runtime_resume_and_get(&client->dev);276		if (ret < 0)277			return ret;278 279		mutex_lock(&tw9900->mutex);280 281		ret = __v4l2_ctrl_handler_setup(sd->ctrl_handler);282		if (ret)283			goto err_unlock;284 285		ret = tw9900_write_array(tw9900->client,286					 tw9900->cur_mode->reg_list,287					 tw9900->cur_mode->n_regs);288		if (ret)289			goto err_unlock;290 291		ret = tw9900_write_reg(client, TW9900_REG_OUT_FMT_CTL,292				       TW9900_REG_OUT_FMT_CTL_STREAMING);293		if (ret)294			goto err_unlock;295 296		tw9900->streaming = on;297 298		mutex_unlock(&tw9900->mutex);299 300	} else {301		mutex_lock(&tw9900->mutex);302 303		ret = tw9900_write_reg(client, TW9900_REG_OUT_FMT_CTL,304				       TW9900_REG_OUT_FMT_CTL_STANDBY);305		if (ret)306			goto err_unlock;307 308		tw9900->streaming = on;309 310		mutex_unlock(&tw9900->mutex);311 312		pm_runtime_put(&client->dev);313	}314 315	return 0;316 317err_unlock:318	mutex_unlock(&tw9900->mutex);319	pm_runtime_put(&client->dev);320 321	return ret;322}323 324static int tw9900_subscribe_event(struct v4l2_subdev *sd,325				  struct v4l2_fh *fh,326				  struct v4l2_event_subscription *sub)327{328	switch (sub->type) {329	case V4L2_EVENT_SOURCE_CHANGE:330		return v4l2_src_change_event_subdev_subscribe(sd, fh, sub);331	case V4L2_EVENT_CTRL:332		return v4l2_ctrl_subdev_subscribe_event(sd, fh, sub);333	default:334		return -EINVAL;335	}336}337 338static int tw9900_s_std(struct v4l2_subdev *sd, v4l2_std_id std)339{340	struct tw9900 *tw9900 = to_tw9900(sd);341	const struct tw9900_mode *mode = NULL;342	int i;343 344	if (!(std & (V4L2_STD_NTSC | V4L2_STD_PAL)))345		return -EINVAL;346 347	for (i = 0; i < ARRAY_SIZE(supported_modes); i++)348		if (supported_modes[i].std & std)349			mode = &supported_modes[i];350	if (!mode)351		return -EINVAL;352 353	mutex_lock(&tw9900->mutex);354	tw9900->cur_mode = mode;355	mutex_unlock(&tw9900->mutex);356 357	return 0;358}359 360static int tw9900_get_stream_std(struct tw9900 *tw9900,361				 v4l2_std_id *std)362{363	int cur_std, ret;364 365	lockdep_assert_held(&tw9900->mutex);366 367	ret = tw9900_read_reg(tw9900->client, TW9900_REG_STD);368	if (ret < 0) {369		*std = V4L2_STD_UNKNOWN;370		return ret;371	}372 373	cur_std = FIELD_GET(TW9900_STDNOW_MASK, ret);374	switch (cur_std) {375	case TW9900_STD_NTSC_M:376		*std = V4L2_STD_NTSC;377		break;378	case TW9900_STD_PAL_BDGHI:379		*std = V4L2_STD_PAL;380		break;381	case TW9900_STD_AUTO:382		*std = V4L2_STD_UNKNOWN;383		break;384	default:385		*std = V4L2_STD_UNKNOWN;386		break;387	}388 389	return 0;390}391 392static int tw9900_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)393{394	struct tw9900 *tw9900 = to_tw9900(sd);395 396	mutex_lock(&tw9900->mutex);397	*std = tw9900->cur_mode->std;398	mutex_unlock(&tw9900->mutex);399 400	return 0;401}402 403static int tw9900_start_autodetect(struct tw9900 *tw9900)404{405	int ret;406 407	lockdep_assert_held(&tw9900->mutex);408 409	ret = tw9900_write_reg(tw9900->client, TW9900_REG_STDR,410			       BIT(TW9900_STD_NTSC_M) |411			       BIT(TW9900_STD_PAL_BDGHI));412	if (ret)413		return ret;414 415	ret = tw9900_write_reg(tw9900->client, TW9900_REG_STD,416			       TW9900_STD_AUTO);417	if (ret)418		return ret;419 420	ret = tw9900_write_reg(tw9900->client, TW9900_REG_STDR,421			       BIT(TW9900_STD_NTSC_M) |422			       BIT(TW9900_STD_PAL_BDGHI) |423			       BIT(TW9900_STD_AUTO));424	if (ret)425		return ret;426 427	/*428	 * Autodetect takes a while to start, and during the starting sequence429	 * the autodetection status is reported as done.430	 */431	msleep(30);432 433	return 0;434}435 436static int tw9900_detect_done(struct tw9900 *tw9900, bool *done)437{438	int ret;439 440	lockdep_assert_held(&tw9900->mutex);441 442	ret = tw9900_read_reg(tw9900->client, TW9900_REG_STD);443	if (ret < 0)444		return ret;445 446	*done = !(ret & TW9900_REG_STD_AUTO_PROGRESS);447 448	return 0;449}450 451static int tw9900_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)452{453	struct tw9900 *tw9900 = to_tw9900(sd);454	bool done = false;455	int i, ret;456 457	mutex_lock(&tw9900->mutex);458 459	if (tw9900->streaming) {460		mutex_unlock(&tw9900->mutex);461		return -EBUSY;462	}463 464	mutex_unlock(&tw9900->mutex);465 466	ret = pm_runtime_resume_and_get(&tw9900->client->dev);467	if (ret < 0)468		return ret;469 470	mutex_lock(&tw9900->mutex);471 472	ret = tw9900_start_autodetect(tw9900);473	if (ret)474		goto out_unlock;475 476	for (i = 0; i < TW9900_VIDEO_POLL_TRIES; i++) {477		ret = tw9900_detect_done(tw9900, &done);478		if (ret)479			goto out_unlock;480 481		if (done)482			break;483 484		msleep(20);485	}486 487	if (!done) {488		ret = -ETIMEDOUT;489		goto out_unlock;490	}491 492	ret = tw9900_get_stream_std(tw9900, std);493 494out_unlock:495	mutex_unlock(&tw9900->mutex);496	pm_runtime_put(&tw9900->client->dev);497 498	return ret;499}500 501static int tw9900_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std)502{503	*std = V4L2_STD_NTSC | V4L2_STD_PAL;504 505	return 0;506}507 508static int tw9900_g_input_status(struct v4l2_subdev *sd, u32 *status)509{510	struct tw9900 *tw9900 = to_tw9900(sd);511	int ret;512 513	mutex_lock(&tw9900->mutex);514 515	if (tw9900->streaming) {516		mutex_unlock(&tw9900->mutex);517		return -EBUSY;518	}519 520	mutex_unlock(&tw9900->mutex);521 522	*status = V4L2_IN_ST_NO_SIGNAL;523 524	ret = pm_runtime_resume_and_get(&tw9900->client->dev);525	if (ret < 0)526		return ret;527 528	mutex_lock(&tw9900->mutex);529	ret = tw9900_read_reg(tw9900->client, TW9900_REG_CHIP_STATUS);530	mutex_unlock(&tw9900->mutex);531 532	pm_runtime_put(&tw9900->client->dev);533 534	if (ret < 0)535		return ret;536 537	*status = ret & TW9900_REG_CHIP_STATUS_HLOCK ? 0 : V4L2_IN_ST_NO_SIGNAL;538 539	return 0;540}541 542static const struct v4l2_subdev_core_ops tw9900_core_ops = {543	.subscribe_event	= tw9900_subscribe_event,544	.unsubscribe_event	= v4l2_event_subdev_unsubscribe,545};546 547static const struct v4l2_subdev_video_ops tw9900_video_ops = {548	.s_std		= tw9900_s_std,549	.g_std		= tw9900_g_std,550	.querystd	= tw9900_querystd,551	.g_tvnorms	= tw9900_g_tvnorms,552	.g_input_status = tw9900_g_input_status,553	.s_stream	= tw9900_s_stream,554};555 556static const struct v4l2_subdev_pad_ops tw9900_pad_ops = {557	.enum_mbus_code	= tw9900_enum_mbus_code,558	.get_fmt	= tw9900_get_fmt,559	.set_fmt	= tw9900_set_fmt,560};561 562static const struct v4l2_subdev_ops tw9900_subdev_ops = {563	.core	= &tw9900_core_ops,564	.video	= &tw9900_video_ops,565	.pad	= &tw9900_pad_ops,566};567 568static const struct v4l2_ctrl_ops tw9900_ctrl_ops = {569	.s_ctrl	= tw9900_s_ctrl,570};571 572static int tw9900_check_id(struct tw9900 *tw9900,573			   struct i2c_client *client)574{575	struct device *dev = &tw9900->client->dev;576	int ret;577 578	ret = pm_runtime_resume_and_get(&tw9900->client->dev);579	if (ret < 0)580		return ret;581 582	mutex_lock(&tw9900->mutex);583	ret = tw9900_read_reg(client, TW9900_CHIP_ID);584	mutex_unlock(&tw9900->mutex);585 586	pm_runtime_put(&tw9900->client->dev);587 588	if (ret < 0)589		return ret;590 591	if (ret != TW9900_CHIP_ID) {592		dev_err(dev, "Unexpected decoder id %#x\n", ret);593		return -ENODEV;594	}595 596	return 0;597}598 599static int tw9900_runtime_resume(struct device *dev)600{601	struct i2c_client *client = to_i2c_client(dev);602	struct v4l2_subdev *sd = i2c_get_clientdata(client);603	struct tw9900 *tw9900 = to_tw9900(sd);604	int ret;605 606	mutex_lock(&tw9900->mutex);607 608	if (tw9900->reset_gpio)609		gpiod_set_value_cansleep(tw9900->reset_gpio, 1);610 611	ret = regulator_enable(tw9900->regulator);612	if (ret < 0) {613		mutex_unlock(&tw9900->mutex);614		return ret;615	}616 617	usleep_range(50000, 52000);618 619	if (tw9900->reset_gpio)620		gpiod_set_value_cansleep(tw9900->reset_gpio, 0);621 622	usleep_range(1000, 2000);623 624	ret = tw9900_write_array(tw9900->client, tw9900_init_regs,625				 ARRAY_SIZE(tw9900_init_regs));626 627	mutex_unlock(&tw9900->mutex);628 629	/* This sleep is needed for the Horizontal Sync PLL to lock. */630	msleep(300);631 632	return ret;633}634 635static int tw9900_runtime_suspend(struct device *dev)636{637	struct i2c_client *client = to_i2c_client(dev);638	struct v4l2_subdev *sd = i2c_get_clientdata(client);639	struct tw9900 *tw9900 = to_tw9900(sd);640 641	mutex_lock(&tw9900->mutex);642 643	if (tw9900->reset_gpio)644		gpiod_set_value_cansleep(tw9900->reset_gpio, 1);645 646	regulator_disable(tw9900->regulator);647 648	mutex_unlock(&tw9900->mutex);649 650	return 0;651}652 653static int tw9900_probe(struct i2c_client *client)654{655	struct device *dev = &client->dev;656	struct v4l2_ctrl_handler *hdl;657	struct tw9900 *tw9900;658	int ret = 0;659 660	tw9900 = devm_kzalloc(dev, sizeof(*tw9900), GFP_KERNEL);661	if (!tw9900)662		return -ENOMEM;663 664	tw9900->client = client;665	tw9900->cur_mode = &supported_modes[0];666 667	tw9900->reset_gpio = devm_gpiod_get_optional(dev, "reset",668						     GPIOD_OUT_LOW);669	if (IS_ERR(tw9900->reset_gpio))670		return dev_err_probe(dev, PTR_ERR(tw9900->reset_gpio),671				     "Failed to get reset gpio\n");672 673	tw9900->regulator = devm_regulator_get(&tw9900->client->dev, "vdd");674	if (IS_ERR(tw9900->regulator))675		return dev_err_probe(dev, PTR_ERR(tw9900->regulator),676				     "Failed to get power regulator\n");677 678	v4l2_i2c_subdev_init(&tw9900->subdev, client, &tw9900_subdev_ops);679	tw9900->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |680				V4L2_SUBDEV_FL_HAS_EVENTS;681 682	mutex_init(&tw9900->mutex);683 684	hdl = &tw9900->hdl;685 686	ret = v4l2_ctrl_handler_init(hdl, 2);687	if (ret)688		goto err_destory_mutex;689 690	hdl->lock = &tw9900->mutex;691 692	v4l2_ctrl_new_std(hdl, &tw9900_ctrl_ops, V4L2_CID_BRIGHTNESS,693			  -128, 127, 1, 0);694	v4l2_ctrl_new_std(hdl, &tw9900_ctrl_ops, V4L2_CID_CONTRAST,695			  0, 255, 1, 0x60);696 697	tw9900->subdev.ctrl_handler = hdl;698	if (hdl->error) {699		ret = hdl->error;700		goto err_free_handler;701	}702 703	tw9900->pad.flags = MEDIA_PAD_FL_SOURCE;704	tw9900->subdev.entity.function = MEDIA_ENT_F_DV_DECODER;705 706	ret = media_entity_pads_init(&tw9900->subdev.entity, 1, &tw9900->pad);707	if (ret < 0)708		goto err_free_handler;709 710	pm_runtime_set_suspended(dev);711	pm_runtime_enable(dev);712 713	ret = tw9900_check_id(tw9900, client);714	if (ret)715		goto err_disable_pm;716 717	ret = v4l2_async_register_subdev(&tw9900->subdev);718	if (ret) {719		dev_err(dev, "v4l2 async register subdev failed\n");720		goto err_disable_pm;721	}722 723	return 0;724 725err_disable_pm:726	pm_runtime_disable(dev);727	media_entity_cleanup(&tw9900->subdev.entity);728err_free_handler:729	v4l2_ctrl_handler_free(hdl);730err_destory_mutex:731	mutex_destroy(&tw9900->mutex);732 733	return ret;734}735 736static void tw9900_remove(struct i2c_client *client)737{738	struct v4l2_subdev *sd = i2c_get_clientdata(client);739	struct tw9900 *tw9900 = to_tw9900(sd);740 741	v4l2_async_unregister_subdev(sd);742	media_entity_cleanup(&sd->entity);743	v4l2_ctrl_handler_free(sd->ctrl_handler);744 745	pm_runtime_disable(&client->dev);746 747	mutex_destroy(&tw9900->mutex);748}749 750static const struct dev_pm_ops tw9900_pm_ops = {751	.runtime_suspend = tw9900_runtime_suspend,752	.runtime_resume = tw9900_runtime_resume,753};754 755static const struct i2c_device_id tw9900_id[] = {756	{ "tw9900" },757	{ }758};759MODULE_DEVICE_TABLE(i2c, tw9900_id);760 761static const struct of_device_id tw9900_of_match[] = {762	{ .compatible = "techwell,tw9900" },763	{},764};765MODULE_DEVICE_TABLE(of, tw9900_of_match);766 767static struct i2c_driver tw9900_i2c_driver = {768	.driver = {769		.name		= "tw9900",770		.pm		= &tw9900_pm_ops,771		.of_match_table	= tw9900_of_match,772	},773	.probe	  = tw9900_probe,774	.remove	  = tw9900_remove,775	.id_table = tw9900_id,776};777 778module_i2c_driver(tw9900_i2c_driver);779 780MODULE_DESCRIPTION("tw9900 decoder driver");781MODULE_LICENSE("GPL");782