diff options
Diffstat (limited to 'drivers/media/usb/cx231xx/cx231xx-cards.c')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-cards.c | 144 |
1 files changed, 137 insertions, 7 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index da03733690bd..fe00da105e77 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c | |||
@@ -776,6 +776,45 @@ struct cx231xx_board cx231xx_boards[] = { | |||
776 | .gpio = NULL, | 776 | .gpio = NULL, |
777 | } }, | 777 | } }, |
778 | }, | 778 | }, |
779 | [CX231XX_BOARD_HAUPPAUGE_955Q] = { | ||
780 | .name = "Hauppauge WinTV-HVR-955Q (111401)", | ||
781 | .tuner_type = TUNER_ABSENT, | ||
782 | .tuner_addr = 0x60, | ||
783 | .tuner_gpio = RDE250_XCV_TUNER, | ||
784 | .tuner_sif_gpio = 0x05, | ||
785 | .tuner_scl_gpio = 0x1a, | ||
786 | .tuner_sda_gpio = 0x1b, | ||
787 | .decoder = CX231XX_AVDECODER, | ||
788 | .output_mode = OUT_MODE_VIP11, | ||
789 | .demod_xfer_mode = 0, | ||
790 | .ctl_pin_status_mask = 0xFFFFFFC4, | ||
791 | .agc_analog_digital_select_gpio = 0x0c, | ||
792 | .gpio_pin_status_mask = 0x4001000, | ||
793 | .tuner_i2c_master = I2C_1_MUX_3, | ||
794 | .demod_i2c_master = I2C_2, | ||
795 | .has_dvb = 1, | ||
796 | .demod_addr = 0x0e, | ||
797 | .norm = V4L2_STD_NTSC, | ||
798 | |||
799 | .input = {{ | ||
800 | .type = CX231XX_VMUX_TELEVISION, | ||
801 | .vmux = CX231XX_VIN_3_1, | ||
802 | .amux = CX231XX_AMUX_VIDEO, | ||
803 | .gpio = NULL, | ||
804 | }, { | ||
805 | .type = CX231XX_VMUX_COMPOSITE1, | ||
806 | .vmux = CX231XX_VIN_2_1, | ||
807 | .amux = CX231XX_AMUX_LINE_IN, | ||
808 | .gpio = NULL, | ||
809 | }, { | ||
810 | .type = CX231XX_VMUX_SVIDEO, | ||
811 | .vmux = CX231XX_VIN_1_1 | | ||
812 | (CX231XX_VIN_1_2 << 8) | | ||
813 | CX25840_SVIDEO_ON, | ||
814 | .amux = CX231XX_AMUX_LINE_IN, | ||
815 | .gpio = NULL, | ||
816 | } }, | ||
817 | }, | ||
779 | }; | 818 | }; |
780 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); | 819 | const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); |
781 | 820 | ||
@@ -805,6 +844,8 @@ struct usb_device_id cx231xx_id_table[] = { | |||
805 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, | 844 | .driver_info = CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC}, |
806 | {USB_DEVICE(0x2040, 0xb120), | 845 | {USB_DEVICE(0x2040, 0xb120), |
807 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, | 846 | .driver_info = CX231XX_BOARD_HAUPPAUGE_EXETER}, |
847 | {USB_DEVICE(0x2040, 0xb123), | ||
848 | .driver_info = CX231XX_BOARD_HAUPPAUGE_955Q}, | ||
808 | {USB_DEVICE(0x2040, 0xb130), | 849 | {USB_DEVICE(0x2040, 0xb130), |
809 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, | 850 | .driver_info = CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx}, |
810 | {USB_DEVICE(0x2040, 0xb131), | 851 | {USB_DEVICE(0x2040, 0xb131), |
@@ -912,9 +953,6 @@ static inline void cx231xx_set_model(struct cx231xx *dev) | |||
912 | */ | 953 | */ |
913 | void cx231xx_pre_card_setup(struct cx231xx *dev) | 954 | void cx231xx_pre_card_setup(struct cx231xx *dev) |
914 | { | 955 | { |
915 | |||
916 | cx231xx_set_model(dev); | ||
917 | |||
918 | dev_info(dev->dev, "Identified as %s (card=%d)\n", | 956 | dev_info(dev->dev, "Identified as %s (card=%d)\n", |
919 | dev->board.name, dev->model); | 957 | dev->board.name, dev->model); |
920 | 958 | ||
@@ -1052,6 +1090,7 @@ void cx231xx_card_setup(struct cx231xx *dev) | |||
1052 | switch (dev->model) { | 1090 | switch (dev->model) { |
1053 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: | 1091 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: |
1054 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: | 1092 | case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: |
1093 | case CX231XX_BOARD_HAUPPAUGE_955Q: | ||
1055 | { | 1094 | { |
1056 | struct tveeprom tvee; | 1095 | struct tveeprom tvee; |
1057 | static u8 eeprom[256]; | 1096 | static u8 eeprom[256]; |
@@ -1092,6 +1131,17 @@ void cx231xx_config_i2c(struct cx231xx *dev) | |||
1092 | call_all(dev, video, s_stream, 1); | 1131 | call_all(dev, video, s_stream, 1); |
1093 | } | 1132 | } |
1094 | 1133 | ||
1134 | static void cx231xx_unregister_media_device(struct cx231xx *dev) | ||
1135 | { | ||
1136 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1137 | if (dev->media_dev) { | ||
1138 | media_device_unregister(dev->media_dev); | ||
1139 | kfree(dev->media_dev); | ||
1140 | dev->media_dev = NULL; | ||
1141 | } | ||
1142 | #endif | ||
1143 | } | ||
1144 | |||
1095 | /* | 1145 | /* |
1096 | * cx231xx_realease_resources() | 1146 | * cx231xx_realease_resources() |
1097 | * unregisters the v4l2,i2c and usb devices | 1147 | * unregisters the v4l2,i2c and usb devices |
@@ -1099,6 +1149,8 @@ void cx231xx_config_i2c(struct cx231xx *dev) | |||
1099 | */ | 1149 | */ |
1100 | void cx231xx_release_resources(struct cx231xx *dev) | 1150 | void cx231xx_release_resources(struct cx231xx *dev) |
1101 | { | 1151 | { |
1152 | cx231xx_unregister_media_device(dev); | ||
1153 | |||
1102 | cx231xx_release_analog_resources(dev); | 1154 | cx231xx_release_analog_resources(dev); |
1103 | 1155 | ||
1104 | cx231xx_remove_from_devlist(dev); | 1156 | cx231xx_remove_from_devlist(dev); |
@@ -1117,6 +1169,74 @@ void cx231xx_release_resources(struct cx231xx *dev) | |||
1117 | clear_bit(dev->devno, &cx231xx_devused); | 1169 | clear_bit(dev->devno, &cx231xx_devused); |
1118 | } | 1170 | } |
1119 | 1171 | ||
1172 | static void cx231xx_media_device_register(struct cx231xx *dev, | ||
1173 | struct usb_device *udev) | ||
1174 | { | ||
1175 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1176 | struct media_device *mdev; | ||
1177 | int ret; | ||
1178 | |||
1179 | mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); | ||
1180 | if (!mdev) | ||
1181 | return; | ||
1182 | |||
1183 | mdev->dev = dev->dev; | ||
1184 | strlcpy(mdev->model, dev->board.name, sizeof(mdev->model)); | ||
1185 | if (udev->serial) | ||
1186 | strlcpy(mdev->serial, udev->serial, sizeof(mdev->serial)); | ||
1187 | strcpy(mdev->bus_info, udev->devpath); | ||
1188 | mdev->hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); | ||
1189 | mdev->driver_version = LINUX_VERSION_CODE; | ||
1190 | |||
1191 | ret = media_device_register(mdev); | ||
1192 | if (ret) { | ||
1193 | dev_err(dev->dev, | ||
1194 | "Couldn't create a media device. Error: %d\n", | ||
1195 | ret); | ||
1196 | kfree(mdev); | ||
1197 | return; | ||
1198 | } | ||
1199 | |||
1200 | dev->media_dev = mdev; | ||
1201 | #endif | ||
1202 | } | ||
1203 | |||
1204 | static void cx231xx_create_media_graph(struct cx231xx *dev) | ||
1205 | { | ||
1206 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1207 | struct media_device *mdev = dev->media_dev; | ||
1208 | struct media_entity *entity; | ||
1209 | struct media_entity *tuner = NULL, *decoder = NULL; | ||
1210 | |||
1211 | if (!mdev) | ||
1212 | return; | ||
1213 | |||
1214 | media_device_for_each_entity(entity, mdev) { | ||
1215 | switch (entity->type) { | ||
1216 | case MEDIA_ENT_T_V4L2_SUBDEV_TUNER: | ||
1217 | tuner = entity; | ||
1218 | break; | ||
1219 | case MEDIA_ENT_T_V4L2_SUBDEV_DECODER: | ||
1220 | decoder = entity; | ||
1221 | break; | ||
1222 | } | ||
1223 | } | ||
1224 | |||
1225 | /* Analog setup, using tuner as a link */ | ||
1226 | |||
1227 | if (!decoder) | ||
1228 | return; | ||
1229 | |||
1230 | if (tuner) | ||
1231 | media_entity_create_link(tuner, 0, decoder, 0, | ||
1232 | MEDIA_LNK_FL_ENABLED); | ||
1233 | media_entity_create_link(decoder, 1, &dev->vdev.entity, 0, | ||
1234 | MEDIA_LNK_FL_ENABLED); | ||
1235 | media_entity_create_link(decoder, 2, &dev->vbi_dev.entity, 0, | ||
1236 | MEDIA_LNK_FL_ENABLED); | ||
1237 | #endif | ||
1238 | } | ||
1239 | |||
1120 | /* | 1240 | /* |
1121 | * cx231xx_init_dev() | 1241 | * cx231xx_init_dev() |
1122 | * allocates and inits the device structs, registers i2c bus and v4l device | 1242 | * allocates and inits the device structs, registers i2c bus and v4l device |
@@ -1225,10 +1345,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1225 | } | 1345 | } |
1226 | 1346 | ||
1227 | retval = cx231xx_register_analog_devices(dev); | 1347 | retval = cx231xx_register_analog_devices(dev); |
1228 | if (retval) { | 1348 | if (retval) |
1229 | cx231xx_release_analog_resources(dev); | ||
1230 | goto err_analog; | 1349 | goto err_analog; |
1231 | } | ||
1232 | 1350 | ||
1233 | cx231xx_ir_init(dev); | 1351 | cx231xx_ir_init(dev); |
1234 | 1352 | ||
@@ -1236,6 +1354,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev, | |||
1236 | 1354 | ||
1237 | return 0; | 1355 | return 0; |
1238 | err_analog: | 1356 | err_analog: |
1357 | cx231xx_unregister_media_device(dev); | ||
1358 | cx231xx_release_analog_resources(dev); | ||
1239 | cx231xx_remove_from_devlist(dev); | 1359 | cx231xx_remove_from_devlist(dev); |
1240 | err_dev_init: | 1360 | err_dev_init: |
1241 | cx231xx_dev_uninit(dev); | 1361 | cx231xx_dev_uninit(dev); |
@@ -1438,6 +1558,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1438 | dev->video_mode.alt = -1; | 1558 | dev->video_mode.alt = -1; |
1439 | dev->dev = d; | 1559 | dev->dev = d; |
1440 | 1560 | ||
1561 | cx231xx_set_model(dev); | ||
1562 | |||
1441 | dev->interface_count++; | 1563 | dev->interface_count++; |
1442 | /* reset gpio dir and value */ | 1564 | /* reset gpio dir and value */ |
1443 | dev->gpio_dir = 0; | 1565 | dev->gpio_dir = 0; |
@@ -1502,7 +1624,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1502 | /* save our data pointer in this interface device */ | 1624 | /* save our data pointer in this interface device */ |
1503 | usb_set_intfdata(interface, dev); | 1625 | usb_set_intfdata(interface, dev); |
1504 | 1626 | ||
1627 | /* Register the media controller */ | ||
1628 | cx231xx_media_device_register(dev, udev); | ||
1629 | |||
1505 | /* Create v4l2 device */ | 1630 | /* Create v4l2 device */ |
1631 | #ifdef CONFIG_MEDIA_CONTROLLER | ||
1632 | dev->v4l2_dev.mdev = dev->media_dev; | ||
1633 | #endif | ||
1506 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | 1634 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); |
1507 | if (retval) { | 1635 | if (retval) { |
1508 | dev_err(d, "v4l2_device_register failed\n"); | 1636 | dev_err(d, "v4l2_device_register failed\n"); |
@@ -1568,6 +1696,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface, | |||
1568 | /* load other modules required */ | 1696 | /* load other modules required */ |
1569 | request_modules(dev); | 1697 | request_modules(dev); |
1570 | 1698 | ||
1699 | cx231xx_create_media_graph(dev); | ||
1700 | |||
1571 | return 0; | 1701 | return 0; |
1572 | err_video_alt: | 1702 | err_video_alt: |
1573 | /* cx231xx_uninit_dev: */ | 1703 | /* cx231xx_uninit_dev: */ |
@@ -1618,7 +1748,7 @@ static void cx231xx_usb_disconnect(struct usb_interface *interface) | |||
1618 | if (dev->users) { | 1748 | if (dev->users) { |
1619 | dev_warn(dev->dev, | 1749 | dev_warn(dev->dev, |
1620 | "device %s is open! Deregistration and memory deallocation are deferred on close.\n", | 1750 | "device %s is open! Deregistration and memory deallocation are deferred on close.\n", |
1621 | video_device_node_name(dev->vdev)); | 1751 | video_device_node_name(&dev->vdev)); |
1622 | 1752 | ||
1623 | /* Even having users, it is safe to remove the RC i2c driver */ | 1753 | /* Even having users, it is safe to remove the RC i2c driver */ |
1624 | cx231xx_ir_exit(dev); | 1754 | cx231xx_ir_exit(dev); |