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