.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * |
---|
3 | 4 | * device driver for Conexant 2388x based TV cards |
---|
.. | .. |
---|
9 | 10 | * - Multituner support |
---|
10 | 11 | * - video_ioctl2 conversion |
---|
11 | 12 | * - PAL/M fixes |
---|
12 | | - * |
---|
13 | | - * This program is free software; you can redistribute it and/or modify |
---|
14 | | - * it under the terms of the GNU General Public License as published by |
---|
15 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
16 | | - * (at your option) any later version. |
---|
17 | | - * |
---|
18 | | - * This program is distributed in the hope that it will be useful, |
---|
19 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
20 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
21 | | - * GNU General Public License for more details. |
---|
22 | 13 | */ |
---|
23 | 14 | |
---|
24 | 15 | #include "cx88.h" |
---|
.. | .. |
---|
42 | 33 | |
---|
43 | 34 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
---|
44 | 35 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
---|
45 | | -MODULE_LICENSE("GPL"); |
---|
| 36 | +MODULE_LICENSE("GPL v2"); |
---|
46 | 37 | MODULE_VERSION(CX88_VERSION); |
---|
47 | 38 | |
---|
48 | 39 | /* ------------------------------------------------------------------ */ |
---|
.. | .. |
---|
78 | 69 | |
---|
79 | 70 | static const struct cx8800_fmt formats[] = { |
---|
80 | 71 | { |
---|
81 | | - .name = "8 bpp, gray", |
---|
82 | 72 | .fourcc = V4L2_PIX_FMT_GREY, |
---|
83 | 73 | .cxformat = ColorFormatY8, |
---|
84 | 74 | .depth = 8, |
---|
85 | 75 | .flags = FORMAT_FLAGS_PACKED, |
---|
86 | 76 | }, { |
---|
87 | | - .name = "15 bpp RGB, le", |
---|
88 | 77 | .fourcc = V4L2_PIX_FMT_RGB555, |
---|
89 | 78 | .cxformat = ColorFormatRGB15, |
---|
90 | 79 | .depth = 16, |
---|
91 | 80 | .flags = FORMAT_FLAGS_PACKED, |
---|
92 | 81 | }, { |
---|
93 | | - .name = "15 bpp RGB, be", |
---|
94 | 82 | .fourcc = V4L2_PIX_FMT_RGB555X, |
---|
95 | 83 | .cxformat = ColorFormatRGB15 | ColorFormatBSWAP, |
---|
96 | 84 | .depth = 16, |
---|
97 | 85 | .flags = FORMAT_FLAGS_PACKED, |
---|
98 | 86 | }, { |
---|
99 | | - .name = "16 bpp RGB, le", |
---|
100 | 87 | .fourcc = V4L2_PIX_FMT_RGB565, |
---|
101 | 88 | .cxformat = ColorFormatRGB16, |
---|
102 | 89 | .depth = 16, |
---|
103 | 90 | .flags = FORMAT_FLAGS_PACKED, |
---|
104 | 91 | }, { |
---|
105 | | - .name = "16 bpp RGB, be", |
---|
106 | 92 | .fourcc = V4L2_PIX_FMT_RGB565X, |
---|
107 | 93 | .cxformat = ColorFormatRGB16 | ColorFormatBSWAP, |
---|
108 | 94 | .depth = 16, |
---|
109 | 95 | .flags = FORMAT_FLAGS_PACKED, |
---|
110 | 96 | }, { |
---|
111 | | - .name = "24 bpp RGB, le", |
---|
112 | 97 | .fourcc = V4L2_PIX_FMT_BGR24, |
---|
113 | 98 | .cxformat = ColorFormatRGB24, |
---|
114 | 99 | .depth = 24, |
---|
115 | 100 | .flags = FORMAT_FLAGS_PACKED, |
---|
116 | 101 | }, { |
---|
117 | | - .name = "32 bpp RGB, le", |
---|
118 | 102 | .fourcc = V4L2_PIX_FMT_BGR32, |
---|
119 | 103 | .cxformat = ColorFormatRGB32, |
---|
120 | 104 | .depth = 32, |
---|
121 | 105 | .flags = FORMAT_FLAGS_PACKED, |
---|
122 | 106 | }, { |
---|
123 | | - .name = "32 bpp RGB, be", |
---|
124 | 107 | .fourcc = V4L2_PIX_FMT_RGB32, |
---|
125 | 108 | .cxformat = ColorFormatRGB32 | ColorFormatBSWAP | |
---|
126 | 109 | ColorFormatWSWAP, |
---|
127 | 110 | .depth = 32, |
---|
128 | 111 | .flags = FORMAT_FLAGS_PACKED, |
---|
129 | 112 | }, { |
---|
130 | | - .name = "4:2:2, packed, YUYV", |
---|
131 | 113 | .fourcc = V4L2_PIX_FMT_YUYV, |
---|
132 | 114 | .cxformat = ColorFormatYUY2, |
---|
133 | 115 | .depth = 16, |
---|
134 | 116 | .flags = FORMAT_FLAGS_PACKED, |
---|
135 | 117 | }, { |
---|
136 | | - .name = "4:2:2, packed, UYVY", |
---|
137 | 118 | .fourcc = V4L2_PIX_FMT_UYVY, |
---|
138 | 119 | .cxformat = ColorFormatYUY2 | ColorFormatBSWAP, |
---|
139 | 120 | .depth = 16, |
---|
.. | .. |
---|
404 | 385 | return 0; |
---|
405 | 386 | } |
---|
406 | 387 | |
---|
407 | | -#ifdef CONFIG_PM |
---|
408 | | -static int stop_video_dma(struct cx8800_dev *dev) |
---|
| 388 | +static int __maybe_unused stop_video_dma(struct cx8800_dev *dev) |
---|
409 | 389 | { |
---|
410 | 390 | struct cx88_core *core = dev->core; |
---|
411 | 391 | |
---|
.. | .. |
---|
421 | 401 | return 0; |
---|
422 | 402 | } |
---|
423 | 403 | |
---|
424 | | -static int restart_video_queue(struct cx8800_dev *dev, |
---|
425 | | - struct cx88_dmaqueue *q) |
---|
| 404 | +static int __maybe_unused restart_video_queue(struct cx8800_dev *dev, |
---|
| 405 | + struct cx88_dmaqueue *q) |
---|
426 | 406 | { |
---|
427 | 407 | struct cx88_buffer *buf; |
---|
428 | 408 | |
---|
.. | .. |
---|
434 | 414 | } |
---|
435 | 415 | return 0; |
---|
436 | 416 | } |
---|
437 | | -#endif |
---|
438 | 417 | |
---|
439 | 418 | /* ------------------------------------------------------------------ */ |
---|
440 | 419 | |
---|
.. | .. |
---|
452 | 431 | |
---|
453 | 432 | static int buffer_prepare(struct vb2_buffer *vb) |
---|
454 | 433 | { |
---|
| 434 | + int ret; |
---|
455 | 435 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
---|
456 | 436 | struct cx8800_dev *dev = vb->vb2_queue->drv_priv; |
---|
457 | 437 | struct cx88_core *core = dev->core; |
---|
.. | .. |
---|
466 | 446 | |
---|
467 | 447 | switch (core->field) { |
---|
468 | 448 | case V4L2_FIELD_TOP: |
---|
469 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
---|
470 | | - sgt->sgl, 0, UNSET, |
---|
471 | | - buf->bpl, 0, core->height); |
---|
| 449 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
---|
| 450 | + sgt->sgl, 0, UNSET, |
---|
| 451 | + buf->bpl, 0, core->height); |
---|
472 | 452 | break; |
---|
473 | 453 | case V4L2_FIELD_BOTTOM: |
---|
474 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
---|
475 | | - sgt->sgl, UNSET, 0, |
---|
476 | | - buf->bpl, 0, core->height); |
---|
| 454 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
---|
| 455 | + sgt->sgl, UNSET, 0, |
---|
| 456 | + buf->bpl, 0, core->height); |
---|
477 | 457 | break; |
---|
478 | 458 | case V4L2_FIELD_SEQ_TB: |
---|
479 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
---|
480 | | - sgt->sgl, |
---|
481 | | - 0, buf->bpl * (core->height >> 1), |
---|
482 | | - buf->bpl, 0, |
---|
483 | | - core->height >> 1); |
---|
| 459 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
---|
| 460 | + sgt->sgl, |
---|
| 461 | + 0, buf->bpl * (core->height >> 1), |
---|
| 462 | + buf->bpl, 0, |
---|
| 463 | + core->height >> 1); |
---|
484 | 464 | break; |
---|
485 | 465 | case V4L2_FIELD_SEQ_BT: |
---|
486 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
---|
487 | | - sgt->sgl, |
---|
488 | | - buf->bpl * (core->height >> 1), 0, |
---|
489 | | - buf->bpl, 0, |
---|
490 | | - core->height >> 1); |
---|
| 466 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
---|
| 467 | + sgt->sgl, |
---|
| 468 | + buf->bpl * (core->height >> 1), 0, |
---|
| 469 | + buf->bpl, 0, |
---|
| 470 | + core->height >> 1); |
---|
491 | 471 | break; |
---|
492 | 472 | case V4L2_FIELD_INTERLACED: |
---|
493 | 473 | default: |
---|
494 | | - cx88_risc_buffer(dev->pci, &buf->risc, |
---|
495 | | - sgt->sgl, 0, buf->bpl, |
---|
496 | | - buf->bpl, buf->bpl, |
---|
497 | | - core->height >> 1); |
---|
| 474 | + ret = cx88_risc_buffer(dev->pci, &buf->risc, |
---|
| 475 | + sgt->sgl, 0, buf->bpl, |
---|
| 476 | + buf->bpl, buf->bpl, |
---|
| 477 | + core->height >> 1); |
---|
498 | 478 | break; |
---|
499 | 479 | } |
---|
500 | 480 | dprintk(2, |
---|
501 | | - "[%p/%d] buffer_prepare - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", |
---|
502 | | - buf, buf->vb.vb2_buf.index, |
---|
503 | | - core->width, core->height, dev->fmt->depth, dev->fmt->name, |
---|
| 481 | + "[%p/%d] %s - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", |
---|
| 482 | + buf, buf->vb.vb2_buf.index, __func__, |
---|
| 483 | + core->width, core->height, dev->fmt->depth, dev->fmt->fourcc, |
---|
504 | 484 | (unsigned long)buf->risc.dma); |
---|
505 | | - return 0; |
---|
| 485 | + return ret; |
---|
506 | 486 | } |
---|
507 | 487 | |
---|
508 | 488 | static void buffer_finish(struct vb2_buffer *vb) |
---|
.. | .. |
---|
809 | 789 | int cx88_querycap(struct file *file, struct cx88_core *core, |
---|
810 | 790 | struct v4l2_capability *cap) |
---|
811 | 791 | { |
---|
812 | | - struct video_device *vdev = video_devdata(file); |
---|
813 | | - |
---|
814 | | - strlcpy(cap->card, core->board.name, sizeof(cap->card)); |
---|
815 | | - cap->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; |
---|
| 792 | + strscpy(cap->card, core->board.name, sizeof(cap->card)); |
---|
| 793 | + cap->capabilities = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 794 | + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | |
---|
| 795 | + V4L2_CAP_DEVICE_CAPS; |
---|
816 | 796 | if (core->board.tuner_type != UNSET) |
---|
817 | | - cap->device_caps |= V4L2_CAP_TUNER; |
---|
818 | | - switch (vdev->vfl_type) { |
---|
819 | | - case VFL_TYPE_RADIO: |
---|
820 | | - cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; |
---|
821 | | - break; |
---|
822 | | - case VFL_TYPE_GRABBER: |
---|
823 | | - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; |
---|
824 | | - break; |
---|
825 | | - case VFL_TYPE_VBI: |
---|
826 | | - cap->device_caps |= V4L2_CAP_VBI_CAPTURE; |
---|
827 | | - break; |
---|
828 | | - default: |
---|
829 | | - return -EINVAL; |
---|
830 | | - } |
---|
831 | | - cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE | |
---|
832 | | - V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS; |
---|
| 797 | + cap->capabilities |= V4L2_CAP_TUNER; |
---|
833 | 798 | if (core->board.radio.type == CX88_RADIO) |
---|
834 | 799 | cap->capabilities |= V4L2_CAP_RADIO; |
---|
835 | 800 | return 0; |
---|
.. | .. |
---|
842 | 807 | struct cx8800_dev *dev = video_drvdata(file); |
---|
843 | 808 | struct cx88_core *core = dev->core; |
---|
844 | 809 | |
---|
845 | | - strcpy(cap->driver, "cx8800"); |
---|
| 810 | + strscpy(cap->driver, "cx8800", sizeof(cap->driver)); |
---|
846 | 811 | sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); |
---|
847 | 812 | return cx88_querycap(file, core, cap); |
---|
848 | 813 | } |
---|
.. | .. |
---|
853 | 818 | if (unlikely(f->index >= ARRAY_SIZE(formats))) |
---|
854 | 819 | return -EINVAL; |
---|
855 | 820 | |
---|
856 | | - strlcpy(f->description, formats[f->index].name, sizeof(f->description)); |
---|
857 | 821 | f->pixelformat = formats[f->index].fourcc; |
---|
858 | 822 | |
---|
859 | 823 | return 0; |
---|
.. | .. |
---|
897 | 861 | if (!INPUT(n).type) |
---|
898 | 862 | return -EINVAL; |
---|
899 | 863 | i->type = V4L2_INPUT_TYPE_CAMERA; |
---|
900 | | - strcpy(i->name, iname[INPUT(n).type]); |
---|
| 864 | + strscpy(i->name, iname[INPUT(n).type], sizeof(i->name)); |
---|
901 | 865 | if ((INPUT(n).type == CX88_VMUX_TELEVISION) || |
---|
902 | 866 | (INPUT(n).type == CX88_VMUX_CABLE)) |
---|
903 | 867 | i->type = V4L2_INPUT_TYPE_TUNER; |
---|
.. | .. |
---|
952 | 916 | if (t->index != 0) |
---|
953 | 917 | return -EINVAL; |
---|
954 | 918 | |
---|
955 | | - strcpy(t->name, "Television"); |
---|
| 919 | + strscpy(t->name, "Television", sizeof(t->name)); |
---|
956 | 920 | t->capability = V4L2_TUNER_CAP_NORM; |
---|
957 | 921 | t->rangehigh = 0xffffffffUL; |
---|
958 | 922 | call_all(core, tuner, g_tuner, t); |
---|
.. | .. |
---|
1065 | 1029 | if (unlikely(t->index > 0)) |
---|
1066 | 1030 | return -EINVAL; |
---|
1067 | 1031 | |
---|
1068 | | - strcpy(t->name, "Radio"); |
---|
| 1032 | + strscpy(t->name, "Radio", sizeof(t->name)); |
---|
1069 | 1033 | |
---|
1070 | 1034 | call_all(core, tuner, g_tuner, t); |
---|
1071 | 1035 | return 0; |
---|
.. | .. |
---|
1378 | 1342 | if (vc->id == V4L2_CID_CHROMA_AGC) |
---|
1379 | 1343 | core->chroma_agc = vc; |
---|
1380 | 1344 | } |
---|
1381 | | - v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL); |
---|
| 1345 | + v4l2_ctrl_add_handler(&core->video_hdl, &core->audio_hdl, NULL, false); |
---|
1382 | 1346 | |
---|
1383 | 1347 | /* load and configure helper modules */ |
---|
1384 | 1348 | |
---|
.. | .. |
---|
1420 | 1384 | }; |
---|
1421 | 1385 | |
---|
1422 | 1386 | request_module("rtc-isl1208"); |
---|
1423 | | - core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info); |
---|
| 1387 | + core->i2c_rtc = i2c_new_client_device(&core->i2c_adap, &rtc_info); |
---|
1424 | 1388 | } |
---|
1425 | | - /* fall-through */ |
---|
| 1389 | + fallthrough; |
---|
1426 | 1390 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
---|
1427 | 1391 | request_module("ir-kbd-i2c"); |
---|
1428 | 1392 | } |
---|
.. | .. |
---|
1482 | 1446 | video_set_drvdata(&dev->video_dev, dev); |
---|
1483 | 1447 | dev->video_dev.ctrl_handler = &core->video_hdl; |
---|
1484 | 1448 | dev->video_dev.queue = &dev->vb2_vidq; |
---|
1485 | | - err = video_register_device(&dev->video_dev, VFL_TYPE_GRABBER, |
---|
| 1449 | + dev->video_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 1450 | + V4L2_CAP_VIDEO_CAPTURE; |
---|
| 1451 | + if (core->board.tuner_type != UNSET) |
---|
| 1452 | + dev->video_dev.device_caps |= V4L2_CAP_TUNER; |
---|
| 1453 | + err = video_register_device(&dev->video_dev, VFL_TYPE_VIDEO, |
---|
1486 | 1454 | video_nr[core->nr]); |
---|
1487 | 1455 | if (err < 0) { |
---|
1488 | 1456 | pr_err("can't register video device\n"); |
---|
.. | .. |
---|
1495 | 1463 | &cx8800_vbi_template, "vbi"); |
---|
1496 | 1464 | video_set_drvdata(&dev->vbi_dev, dev); |
---|
1497 | 1465 | dev->vbi_dev.queue = &dev->vb2_vbiq; |
---|
| 1466 | + dev->vbi_dev.device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | |
---|
| 1467 | + V4L2_CAP_VBI_CAPTURE; |
---|
| 1468 | + if (core->board.tuner_type != UNSET) |
---|
| 1469 | + dev->vbi_dev.device_caps |= V4L2_CAP_TUNER; |
---|
1498 | 1470 | err = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, |
---|
1499 | 1471 | vbi_nr[core->nr]); |
---|
1500 | 1472 | if (err < 0) { |
---|
.. | .. |
---|
1509 | 1481 | &cx8800_radio_template, "radio"); |
---|
1510 | 1482 | video_set_drvdata(&dev->radio_dev, dev); |
---|
1511 | 1483 | dev->radio_dev.ctrl_handler = &core->audio_hdl; |
---|
| 1484 | + dev->radio_dev.device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; |
---|
1512 | 1485 | err = video_register_device(&dev->radio_dev, VFL_TYPE_RADIO, |
---|
1513 | 1486 | radio_nr[core->nr]); |
---|
1514 | 1487 | if (err < 0) { |
---|
.. | .. |
---|
1577 | 1550 | kfree(dev); |
---|
1578 | 1551 | } |
---|
1579 | 1552 | |
---|
1580 | | -#ifdef CONFIG_PM |
---|
1581 | | -static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state) |
---|
| 1553 | +static int __maybe_unused cx8800_suspend(struct device *dev_d) |
---|
1582 | 1554 | { |
---|
1583 | | - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
---|
| 1555 | + struct cx8800_dev *dev = dev_get_drvdata(dev_d); |
---|
1584 | 1556 | struct cx88_core *core = dev->core; |
---|
1585 | 1557 | unsigned long flags; |
---|
1586 | 1558 | |
---|
.. | .. |
---|
1601 | 1573 | /* FIXME -- shutdown device */ |
---|
1602 | 1574 | cx88_shutdown(core); |
---|
1603 | 1575 | |
---|
1604 | | - pci_save_state(pci_dev); |
---|
1605 | | - if (pci_set_power_state(pci_dev, |
---|
1606 | | - pci_choose_state(pci_dev, state)) != 0) { |
---|
1607 | | - pci_disable_device(pci_dev); |
---|
1608 | | - dev->state.disabled = 1; |
---|
1609 | | - } |
---|
| 1576 | + dev->state.disabled = 1; |
---|
1610 | 1577 | return 0; |
---|
1611 | 1578 | } |
---|
1612 | 1579 | |
---|
1613 | | -static int cx8800_resume(struct pci_dev *pci_dev) |
---|
| 1580 | +static int __maybe_unused cx8800_resume(struct device *dev_d) |
---|
1614 | 1581 | { |
---|
1615 | | - struct cx8800_dev *dev = pci_get_drvdata(pci_dev); |
---|
| 1582 | + struct cx8800_dev *dev = dev_get_drvdata(dev_d); |
---|
1616 | 1583 | struct cx88_core *core = dev->core; |
---|
1617 | 1584 | unsigned long flags; |
---|
1618 | | - int err; |
---|
1619 | 1585 | |
---|
1620 | | - if (dev->state.disabled) { |
---|
1621 | | - err = pci_enable_device(pci_dev); |
---|
1622 | | - if (err) { |
---|
1623 | | - pr_err("can't enable device\n"); |
---|
1624 | | - return err; |
---|
1625 | | - } |
---|
1626 | | - |
---|
1627 | | - dev->state.disabled = 0; |
---|
1628 | | - } |
---|
1629 | | - err = pci_set_power_state(pci_dev, PCI_D0); |
---|
1630 | | - if (err) { |
---|
1631 | | - pr_err("can't set power state\n"); |
---|
1632 | | - pci_disable_device(pci_dev); |
---|
1633 | | - dev->state.disabled = 1; |
---|
1634 | | - |
---|
1635 | | - return err; |
---|
1636 | | - } |
---|
1637 | | - pci_restore_state(pci_dev); |
---|
| 1586 | + dev->state.disabled = 0; |
---|
1638 | 1587 | |
---|
1639 | 1588 | /* FIXME: re-initialize hardware */ |
---|
1640 | 1589 | cx88_reset(core); |
---|
.. | .. |
---|
1657 | 1606 | |
---|
1658 | 1607 | return 0; |
---|
1659 | 1608 | } |
---|
1660 | | -#endif |
---|
1661 | 1609 | |
---|
1662 | 1610 | /* ----------------------------------------------------------- */ |
---|
1663 | 1611 | |
---|
.. | .. |
---|
1673 | 1621 | }; |
---|
1674 | 1622 | MODULE_DEVICE_TABLE(pci, cx8800_pci_tbl); |
---|
1675 | 1623 | |
---|
| 1624 | +static SIMPLE_DEV_PM_OPS(cx8800_pm_ops, cx8800_suspend, cx8800_resume); |
---|
| 1625 | + |
---|
1676 | 1626 | static struct pci_driver cx8800_pci_driver = { |
---|
1677 | | - .name = "cx8800", |
---|
1678 | | - .id_table = cx8800_pci_tbl, |
---|
1679 | | - .probe = cx8800_initdev, |
---|
1680 | | - .remove = cx8800_finidev, |
---|
1681 | | -#ifdef CONFIG_PM |
---|
1682 | | - .suspend = cx8800_suspend, |
---|
1683 | | - .resume = cx8800_resume, |
---|
1684 | | -#endif |
---|
| 1627 | + .name = "cx8800", |
---|
| 1628 | + .id_table = cx8800_pci_tbl, |
---|
| 1629 | + .probe = cx8800_initdev, |
---|
| 1630 | + .remove = cx8800_finidev, |
---|
| 1631 | + .driver.pm = &cx8800_pm_ops, |
---|
1685 | 1632 | }; |
---|
1686 | 1633 | |
---|
1687 | 1634 | module_pci_driver(cx8800_pci_driver); |
---|