diff options
Diffstat (limited to 'drivers/media/dvb-frontends/rtl2832_sdr.c')
| -rw-r--r-- | drivers/media/dvb-frontends/rtl2832_sdr.c | 120 |
1 files changed, 96 insertions, 24 deletions
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index 3ff8806ca584..7edb885ae9c8 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c | |||
| @@ -39,6 +39,10 @@ static bool rtl2832_sdr_emulated_fmt; | |||
| 39 | module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644); | 39 | module_param_named(emulated_formats, rtl2832_sdr_emulated_fmt, bool, 0644); |
| 40 | MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)"); | 40 | MODULE_PARM_DESC(emulated_formats, "enable emulated formats (disappears in future)"); |
| 41 | 41 | ||
| 42 | /* Original macro does not contain enough null pointer checks for our need */ | ||
| 43 | #define V4L2_SUBDEV_HAS_OP(sd, o, f) \ | ||
| 44 | ((sd) && (sd)->ops && (sd)->ops->o && (sd)->ops->o->f) | ||
| 45 | |||
| 42 | #define MAX_BULK_BUFS (10) | 46 | #define MAX_BULK_BUFS (10) |
| 43 | #define BULK_BUFFER_SIZE (128 * 512) | 47 | #define BULK_BUFFER_SIZE (128 * 512) |
| 44 | 48 | ||
| @@ -108,14 +112,15 @@ struct rtl2832_sdr_frame_buf { | |||
| 108 | }; | 112 | }; |
| 109 | 113 | ||
| 110 | struct rtl2832_sdr_dev { | 114 | struct rtl2832_sdr_dev { |
| 111 | #define POWER_ON (1 << 1) | 115 | #define POWER_ON 0 /* BIT(0) */ |
| 112 | #define URB_BUF (1 << 2) | 116 | #define URB_BUF 1 /* BIT(1) */ |
| 113 | unsigned long flags; | 117 | unsigned long flags; |
| 114 | 118 | ||
| 115 | struct platform_device *pdev; | 119 | struct platform_device *pdev; |
| 116 | 120 | ||
| 117 | struct video_device vdev; | 121 | struct video_device vdev; |
| 118 | struct v4l2_device v4l2_dev; | 122 | struct v4l2_device v4l2_dev; |
| 123 | struct v4l2_subdev *v4l2_subdev; | ||
| 119 | 124 | ||
| 120 | /* videobuf2 queue and queued buffers list */ | 125 | /* videobuf2 queue and queued buffers list */ |
| 121 | struct vb2_queue vb_queue; | 126 | struct vb2_queue vb_queue; |
| @@ -351,7 +356,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_dev *dev) | |||
| 351 | { | 356 | { |
| 352 | struct platform_device *pdev = dev->pdev; | 357 | struct platform_device *pdev = dev->pdev; |
| 353 | 358 | ||
| 354 | if (dev->flags & USB_STATE_URB_BUF) { | 359 | if (test_bit(URB_BUF, &dev->flags)) { |
| 355 | while (dev->buf_num) { | 360 | while (dev->buf_num) { |
| 356 | dev->buf_num--; | 361 | dev->buf_num--; |
| 357 | dev_dbg(&pdev->dev, "free buf=%d\n", dev->buf_num); | 362 | dev_dbg(&pdev->dev, "free buf=%d\n", dev->buf_num); |
| @@ -360,7 +365,7 @@ static int rtl2832_sdr_free_stream_bufs(struct rtl2832_sdr_dev *dev) | |||
| 360 | dev->dma_addr[dev->buf_num]); | 365 | dev->dma_addr[dev->buf_num]); |
| 361 | } | 366 | } |
| 362 | } | 367 | } |
| 363 | dev->flags &= ~USB_STATE_URB_BUF; | 368 | clear_bit(URB_BUF, &dev->flags); |
| 364 | 369 | ||
| 365 | return 0; | 370 | return 0; |
| 366 | } | 371 | } |
| @@ -389,7 +394,7 @@ static int rtl2832_sdr_alloc_stream_bufs(struct rtl2832_sdr_dev *dev) | |||
| 389 | dev_dbg(&pdev->dev, "alloc buf=%d %p (dma %llu)\n", | 394 | dev_dbg(&pdev->dev, "alloc buf=%d %p (dma %llu)\n", |
| 390 | dev->buf_num, dev->buf_list[dev->buf_num], | 395 | dev->buf_num, dev->buf_list[dev->buf_num], |
| 391 | (long long)dev->dma_addr[dev->buf_num]); | 396 | (long long)dev->dma_addr[dev->buf_num]); |
| 392 | dev->flags |= USB_STATE_URB_BUF; | 397 | set_bit(URB_BUF, &dev->flags); |
| 393 | } | 398 | } |
| 394 | 399 | ||
| 395 | return 0; | 400 | return 0; |
| @@ -742,6 +747,29 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev) | |||
| 742 | ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); | 747 | ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); |
| 743 | ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xf4", 1); | 748 | ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xf4", 1); |
| 744 | break; | 749 | break; |
| 750 | case RTL2832_SDR_TUNER_FC2580: | ||
| 751 | ret = rtl2832_sdr_wr_regs(dev, 0x112, "\x39", 1); | ||
| 752 | ret = rtl2832_sdr_wr_regs(dev, 0x102, "\x40", 1); | ||
| 753 | ret = rtl2832_sdr_wr_regs(dev, 0x103, "\x5a", 1); | ||
| 754 | ret = rtl2832_sdr_wr_regs(dev, 0x1c7, "\x2c", 1); | ||
| 755 | ret = rtl2832_sdr_wr_regs(dev, 0x104, "\xcc", 1); | ||
| 756 | ret = rtl2832_sdr_wr_regs(dev, 0x105, "\xbe", 1); | ||
| 757 | ret = rtl2832_sdr_wr_regs(dev, 0x1c8, "\x16", 1); | ||
| 758 | ret = rtl2832_sdr_wr_regs(dev, 0x106, "\x35", 1); | ||
| 759 | ret = rtl2832_sdr_wr_regs(dev, 0x1c9, "\x21", 1); | ||
| 760 | ret = rtl2832_sdr_wr_regs(dev, 0x1ca, "\x21", 1); | ||
| 761 | ret = rtl2832_sdr_wr_regs(dev, 0x1cb, "\x00", 1); | ||
| 762 | ret = rtl2832_sdr_wr_regs(dev, 0x107, "\x40", 1); | ||
| 763 | ret = rtl2832_sdr_wr_regs(dev, 0x1cd, "\x10", 1); | ||
| 764 | ret = rtl2832_sdr_wr_regs(dev, 0x1ce, "\x10", 1); | ||
| 765 | ret = rtl2832_sdr_wr_regs(dev, 0x108, "\x80", 1); | ||
| 766 | ret = rtl2832_sdr_wr_regs(dev, 0x109, "\x7f", 1); | ||
| 767 | ret = rtl2832_sdr_wr_regs(dev, 0x10a, "\x9c", 1); | ||
| 768 | ret = rtl2832_sdr_wr_regs(dev, 0x10b, "\x7f", 1); | ||
| 769 | ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); | ||
| 770 | ret = rtl2832_sdr_wr_regs(dev, 0x00e, "\xfc", 1); | ||
| 771 | ret = rtl2832_sdr_wr_regs(dev, 0x011, "\xe9\xf4", 2); | ||
| 772 | break; | ||
| 745 | default: | 773 | default: |
| 746 | dev_notice(&pdev->dev, "Unsupported tuner\n"); | 774 | dev_notice(&pdev->dev, "Unsupported tuner\n"); |
| 747 | } | 775 | } |
| @@ -832,8 +860,10 @@ static int rtl2832_sdr_set_tuner_freq(struct rtl2832_sdr_dev *dev) | |||
| 832 | if (!test_bit(POWER_ON, &dev->flags)) | 860 | if (!test_bit(POWER_ON, &dev->flags)) |
| 833 | return 0; | 861 | return 0; |
| 834 | 862 | ||
| 835 | if (fe->ops.tuner_ops.set_params) | 863 | if (!V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_frequency)) { |
| 836 | fe->ops.tuner_ops.set_params(fe); | 864 | if (fe->ops.tuner_ops.set_params) |
| 865 | fe->ops.tuner_ops.set_params(fe); | ||
| 866 | } | ||
| 837 | 867 | ||
| 838 | return 0; | 868 | return 0; |
| 839 | }; | 869 | }; |
| @@ -891,7 +921,11 @@ static int rtl2832_sdr_start_streaming(struct vb2_queue *vq, unsigned int count) | |||
| 891 | 921 | ||
| 892 | set_bit(POWER_ON, &dev->flags); | 922 | set_bit(POWER_ON, &dev->flags); |
| 893 | 923 | ||
| 894 | ret = rtl2832_sdr_set_tuner(dev); | 924 | /* wake-up tuner */ |
| 925 | if (V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, core, s_power)) | ||
| 926 | ret = v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 1); | ||
| 927 | else | ||
| 928 | ret = rtl2832_sdr_set_tuner(dev); | ||
| 895 | if (ret) | 929 | if (ret) |
| 896 | goto err; | 930 | goto err; |
| 897 | 931 | ||
| @@ -939,7 +973,12 @@ static void rtl2832_sdr_stop_streaming(struct vb2_queue *vq) | |||
| 939 | rtl2832_sdr_free_stream_bufs(dev); | 973 | rtl2832_sdr_free_stream_bufs(dev); |
| 940 | rtl2832_sdr_cleanup_queued_bufs(dev); | 974 | rtl2832_sdr_cleanup_queued_bufs(dev); |
| 941 | rtl2832_sdr_unset_adc(dev); | 975 | rtl2832_sdr_unset_adc(dev); |
| 942 | rtl2832_sdr_unset_tuner(dev); | 976 | |
| 977 | /* sleep tuner */ | ||
| 978 | if (V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, core, s_power)) | ||
| 979 | v4l2_subdev_call(dev->v4l2_subdev, core, s_power, 0); | ||
| 980 | else | ||
| 981 | rtl2832_sdr_unset_tuner(dev); | ||
| 943 | 982 | ||
| 944 | clear_bit(POWER_ON, &dev->flags); | 983 | clear_bit(POWER_ON, &dev->flags); |
| 945 | 984 | ||
| @@ -968,6 +1007,7 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv, | |||
| 968 | { | 1007 | { |
| 969 | struct rtl2832_sdr_dev *dev = video_drvdata(file); | 1008 | struct rtl2832_sdr_dev *dev = video_drvdata(file); |
| 970 | struct platform_device *pdev = dev->pdev; | 1009 | struct platform_device *pdev = dev->pdev; |
| 1010 | int ret; | ||
| 971 | 1011 | ||
| 972 | dev_dbg(&pdev->dev, "index=%d type=%d\n", v->index, v->type); | 1012 | dev_dbg(&pdev->dev, "index=%d type=%d\n", v->index, v->type); |
| 973 | 1013 | ||
| @@ -977,17 +1017,21 @@ static int rtl2832_sdr_g_tuner(struct file *file, void *priv, | |||
| 977 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; | 1017 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; |
| 978 | v->rangelow = 300000; | 1018 | v->rangelow = 300000; |
| 979 | v->rangehigh = 3200000; | 1019 | v->rangehigh = 3200000; |
| 1020 | ret = 0; | ||
| 1021 | } else if (v->index == 1 && | ||
| 1022 | V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_tuner)) { | ||
| 1023 | ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_tuner, v); | ||
| 980 | } else if (v->index == 1) { | 1024 | } else if (v->index == 1) { |
| 981 | strlcpy(v->name, "RF: <unknown>", sizeof(v->name)); | 1025 | strlcpy(v->name, "RF: <unknown>", sizeof(v->name)); |
| 982 | v->type = V4L2_TUNER_RF; | 1026 | v->type = V4L2_TUNER_RF; |
| 983 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; | 1027 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; |
| 984 | v->rangelow = 50000000; | 1028 | v->rangelow = 50000000; |
| 985 | v->rangehigh = 2000000000; | 1029 | v->rangehigh = 2000000000; |
| 1030 | ret = 0; | ||
| 986 | } else { | 1031 | } else { |
| 987 | return -EINVAL; | 1032 | ret = -EINVAL; |
| 988 | } | 1033 | } |
| 989 | 1034 | return ret; | |
| 990 | return 0; | ||
| 991 | } | 1035 | } |
| 992 | 1036 | ||
| 993 | static int rtl2832_sdr_s_tuner(struct file *file, void *priv, | 1037 | static int rtl2832_sdr_s_tuner(struct file *file, void *priv, |
| @@ -995,12 +1039,21 @@ static int rtl2832_sdr_s_tuner(struct file *file, void *priv, | |||
| 995 | { | 1039 | { |
| 996 | struct rtl2832_sdr_dev *dev = video_drvdata(file); | 1040 | struct rtl2832_sdr_dev *dev = video_drvdata(file); |
| 997 | struct platform_device *pdev = dev->pdev; | 1041 | struct platform_device *pdev = dev->pdev; |
| 1042 | int ret; | ||
| 998 | 1043 | ||
| 999 | dev_dbg(&pdev->dev, "\n"); | 1044 | dev_dbg(&pdev->dev, "\n"); |
| 1000 | 1045 | ||
| 1001 | if (v->index > 1) | 1046 | if (v->index == 0) { |
| 1002 | return -EINVAL; | 1047 | ret = 0; |
| 1003 | return 0; | 1048 | } else if (v->index == 1 && |
| 1049 | V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_tuner)) { | ||
| 1050 | ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_tuner, v); | ||
| 1051 | } else if (v->index == 1) { | ||
| 1052 | ret = 0; | ||
| 1053 | } else { | ||
| 1054 | ret = -EINVAL; | ||
| 1055 | } | ||
| 1056 | return ret; | ||
| 1004 | } | 1057 | } |
| 1005 | 1058 | ||
| 1006 | static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, | 1059 | static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, |
| @@ -1008,6 +1061,7 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, | |||
| 1008 | { | 1061 | { |
| 1009 | struct rtl2832_sdr_dev *dev = video_drvdata(file); | 1062 | struct rtl2832_sdr_dev *dev = video_drvdata(file); |
| 1010 | struct platform_device *pdev = dev->pdev; | 1063 | struct platform_device *pdev = dev->pdev; |
| 1064 | int ret; | ||
| 1011 | 1065 | ||
| 1012 | dev_dbg(&pdev->dev, "tuner=%d type=%d index=%d\n", | 1066 | dev_dbg(&pdev->dev, "tuner=%d type=%d index=%d\n", |
| 1013 | band->tuner, band->type, band->index); | 1067 | band->tuner, band->type, band->index); |
| @@ -1017,16 +1071,20 @@ static int rtl2832_sdr_enum_freq_bands(struct file *file, void *priv, | |||
| 1017 | return -EINVAL; | 1071 | return -EINVAL; |
| 1018 | 1072 | ||
| 1019 | *band = bands_adc[band->index]; | 1073 | *band = bands_adc[band->index]; |
| 1074 | ret = 0; | ||
| 1075 | } else if (band->tuner == 1 && | ||
| 1076 | V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, enum_freq_bands)) { | ||
| 1077 | ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, enum_freq_bands, band); | ||
| 1020 | } else if (band->tuner == 1) { | 1078 | } else if (band->tuner == 1) { |
| 1021 | if (band->index >= ARRAY_SIZE(bands_fm)) | 1079 | if (band->index >= ARRAY_SIZE(bands_fm)) |
| 1022 | return -EINVAL; | 1080 | return -EINVAL; |
| 1023 | 1081 | ||
| 1024 | *band = bands_fm[band->index]; | 1082 | *band = bands_fm[band->index]; |
| 1083 | ret = 0; | ||
| 1025 | } else { | 1084 | } else { |
| 1026 | return -EINVAL; | 1085 | ret = -EINVAL; |
| 1027 | } | 1086 | } |
| 1028 | 1087 | return ret; | |
| 1029 | return 0; | ||
| 1030 | } | 1088 | } |
| 1031 | 1089 | ||
| 1032 | static int rtl2832_sdr_g_frequency(struct file *file, void *priv, | 1090 | static int rtl2832_sdr_g_frequency(struct file *file, void *priv, |
| @@ -1034,20 +1092,25 @@ static int rtl2832_sdr_g_frequency(struct file *file, void *priv, | |||
| 1034 | { | 1092 | { |
| 1035 | struct rtl2832_sdr_dev *dev = video_drvdata(file); | 1093 | struct rtl2832_sdr_dev *dev = video_drvdata(file); |
| 1036 | struct platform_device *pdev = dev->pdev; | 1094 | struct platform_device *pdev = dev->pdev; |
| 1037 | int ret = 0; | 1095 | int ret; |
| 1038 | 1096 | ||
| 1039 | dev_dbg(&pdev->dev, "tuner=%d type=%d\n", f->tuner, f->type); | 1097 | dev_dbg(&pdev->dev, "tuner=%d type=%d\n", f->tuner, f->type); |
| 1040 | 1098 | ||
| 1041 | if (f->tuner == 0) { | 1099 | if (f->tuner == 0) { |
| 1042 | f->frequency = dev->f_adc; | 1100 | f->frequency = dev->f_adc; |
| 1043 | f->type = V4L2_TUNER_ADC; | 1101 | f->type = V4L2_TUNER_ADC; |
| 1102 | ret = 0; | ||
| 1103 | } else if (f->tuner == 1 && | ||
| 1104 | V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, g_frequency)) { | ||
| 1105 | f->type = V4L2_TUNER_RF; | ||
| 1106 | ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, g_frequency, f); | ||
| 1044 | } else if (f->tuner == 1) { | 1107 | } else if (f->tuner == 1) { |
| 1045 | f->frequency = dev->f_tuner; | 1108 | f->frequency = dev->f_tuner; |
| 1046 | f->type = V4L2_TUNER_RF; | 1109 | f->type = V4L2_TUNER_RF; |
| 1110 | ret = 0; | ||
| 1047 | } else { | 1111 | } else { |
| 1048 | return -EINVAL; | 1112 | ret = -EINVAL; |
| 1049 | } | 1113 | } |
| 1050 | |||
| 1051 | return ret; | 1114 | return ret; |
| 1052 | } | 1115 | } |
| 1053 | 1116 | ||
| @@ -1074,11 +1137,14 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv, | |||
| 1074 | band = 2; | 1137 | band = 2; |
| 1075 | 1138 | ||
| 1076 | dev->f_adc = clamp_t(unsigned int, f->frequency, | 1139 | dev->f_adc = clamp_t(unsigned int, f->frequency, |
| 1077 | bands_adc[band].rangelow, | 1140 | bands_adc[band].rangelow, |
| 1078 | bands_adc[band].rangehigh); | 1141 | bands_adc[band].rangehigh); |
| 1079 | 1142 | ||
| 1080 | dev_dbg(&pdev->dev, "ADC frequency=%u Hz\n", dev->f_adc); | 1143 | dev_dbg(&pdev->dev, "ADC frequency=%u Hz\n", dev->f_adc); |
| 1081 | ret = rtl2832_sdr_set_adc(dev); | 1144 | ret = rtl2832_sdr_set_adc(dev); |
| 1145 | } else if (f->tuner == 1 && | ||
| 1146 | V4L2_SUBDEV_HAS_OP(dev->v4l2_subdev, tuner, s_frequency)) { | ||
| 1147 | ret = v4l2_subdev_call(dev->v4l2_subdev, tuner, s_frequency, f); | ||
| 1082 | } else if (f->tuner == 1) { | 1148 | } else if (f->tuner == 1) { |
| 1083 | dev->f_tuner = clamp_t(unsigned int, f->frequency, | 1149 | dev->f_tuner = clamp_t(unsigned int, f->frequency, |
| 1084 | bands_fm[0].rangelow, | 1150 | bands_fm[0].rangelow, |
| @@ -1089,7 +1155,6 @@ static int rtl2832_sdr_s_frequency(struct file *file, void *priv, | |||
| 1089 | } else { | 1155 | } else { |
| 1090 | ret = -EINVAL; | 1156 | ret = -EINVAL; |
| 1091 | } | 1157 | } |
| 1092 | |||
| 1093 | return ret; | 1158 | return ret; |
| 1094 | } | 1159 | } |
| 1095 | 1160 | ||
| @@ -1329,6 +1394,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) | |||
| 1329 | 1394 | ||
| 1330 | /* setup the state */ | 1395 | /* setup the state */ |
| 1331 | subdev = pdata->v4l2_subdev; | 1396 | subdev = pdata->v4l2_subdev; |
| 1397 | dev->v4l2_subdev = pdata->v4l2_subdev; | ||
| 1332 | dev->pdev = pdev; | 1398 | dev->pdev = pdev; |
| 1333 | dev->udev = pdata->dvb_usb_device->udev; | 1399 | dev->udev = pdata->dvb_usb_device->udev; |
| 1334 | dev->f_adc = bands_adc[0].rangelow; | 1400 | dev->f_adc = bands_adc[0].rangelow; |
| @@ -1388,6 +1454,12 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) | |||
| 1388 | 6000000); | 1454 | 6000000); |
| 1389 | v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); | 1455 | v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); |
| 1390 | break; | 1456 | break; |
| 1457 | case RTL2832_SDR_TUNER_FC2580: | ||
| 1458 | v4l2_ctrl_handler_init(&dev->hdl, 2); | ||
| 1459 | if (subdev) | ||
| 1460 | v4l2_ctrl_add_handler(&dev->hdl, subdev->ctrl_handler, | ||
| 1461 | NULL); | ||
| 1462 | break; | ||
| 1391 | default: | 1463 | default: |
| 1392 | v4l2_ctrl_handler_init(&dev->hdl, 0); | 1464 | v4l2_ctrl_handler_init(&dev->hdl, 0); |
| 1393 | dev_err(&pdev->dev, "Unsupported tuner\n"); | 1465 | dev_err(&pdev->dev, "Unsupported tuner\n"); |
