diff options
author | Tobias Lorenz <tobias.lorenz@gmx.net> | 2008-05-31 14:07:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:08:34 -0400 |
commit | a7c850a07eddf0e0f515d57b2ce696a9779c6ed1 (patch) | |
tree | 47ab56eb25f7272b1021dccf7776b8e1636cb919 /drivers/media/radio | |
parent | 6cc72658897ee970e4ecfefaae58f043a98a8e65 (diff) |
V4L/DVB (7995): si470x: a lot of small code cleanups
This patch brings the following changes:
- comment on how to listen to an usb audio device
(i get so many questions about that...)
- code cleanup (error handling, more warnings, spacing, ...)
Signed-off-by: Tobias Lorenz <tobias.lorenz@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/radio')
-rw-r--r-- | drivers/media/radio/radio-si470x.c | 286 |
1 files changed, 196 insertions, 90 deletions
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 7df1163d7097..954ba997895d 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c | |||
@@ -101,7 +101,7 @@ | |||
101 | * - unplugging fixed | 101 | * - unplugging fixed |
102 | * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net> | 102 | * 2008-05-07 Tobias Lorenz <tobias.lorenz@gmx.net> |
103 | * Version 1.0.8 | 103 | * Version 1.0.8 |
104 | * - let si470x_get_freq return errno | 104 | * - more safety checks, let si470x_get_freq return errno |
105 | * | 105 | * |
106 | * ToDo: | 106 | * ToDo: |
107 | * - add seeking support | 107 | * - add seeking support |
@@ -487,11 +487,11 @@ static int si470x_get_report(struct si470x_device *radio, void *buf, int size) | |||
487 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 487 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
488 | report[0], 2, | 488 | report[0], 2, |
489 | buf, size, usb_timeout); | 489 | buf, size, usb_timeout); |
490 | |||
490 | if (retval < 0) | 491 | if (retval < 0) |
491 | printk(KERN_WARNING DRIVER_NAME | 492 | printk(KERN_WARNING DRIVER_NAME |
492 | ": si470x_get_report: usb_control_msg returned %d\n", | 493 | ": si470x_get_report: usb_control_msg returned %d\n", |
493 | retval); | 494 | retval); |
494 | |||
495 | return retval; | 495 | return retval; |
496 | } | 496 | } |
497 | 497 | ||
@@ -510,11 +510,11 @@ static int si470x_set_report(struct si470x_device *radio, void *buf, int size) | |||
510 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 510 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
511 | report[0], 2, | 511 | report[0], 2, |
512 | buf, size, usb_timeout); | 512 | buf, size, usb_timeout); |
513 | |||
513 | if (retval < 0) | 514 | if (retval < 0) |
514 | printk(KERN_WARNING DRIVER_NAME | 515 | printk(KERN_WARNING DRIVER_NAME |
515 | ": si470x_set_report: usb_control_msg returned %d\n", | 516 | ": si470x_set_report: usb_control_msg returned %d\n", |
516 | retval); | 517 | retval); |
517 | |||
518 | return retval; | 518 | return retval; |
519 | } | 519 | } |
520 | 520 | ||
@@ -623,24 +623,30 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) | |||
623 | radio->registers[CHANNEL] |= CHANNEL_TUNE | chan; | 623 | radio->registers[CHANNEL] |= CHANNEL_TUNE | chan; |
624 | retval = si470x_set_register(radio, CHANNEL); | 624 | retval = si470x_set_register(radio, CHANNEL); |
625 | if (retval < 0) | 625 | if (retval < 0) |
626 | return retval; | 626 | goto done; |
627 | 627 | ||
628 | /* wait till seek operation has completed */ | 628 | /* wait till tune operation has completed */ |
629 | timeout = jiffies + msecs_to_jiffies(tune_timeout); | 629 | timeout = jiffies + msecs_to_jiffies(tune_timeout); |
630 | do { | 630 | do { |
631 | retval = si470x_get_register(radio, STATUSRSSI); | 631 | retval = si470x_get_register(radio, STATUSRSSI); |
632 | if (retval < 0) | 632 | if (retval < 0) |
633 | return retval; | 633 | goto stop; |
634 | timed_out = time_after(jiffies, timeout); | 634 | timed_out = time_after(jiffies, timeout); |
635 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && | 635 | } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && |
636 | (!timed_out)); | 636 | (!timed_out)); |
637 | if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) | ||
638 | printk(KERN_WARNING DRIVER_NAME ": tune does not complete\n"); | ||
637 | if (timed_out) | 639 | if (timed_out) |
638 | printk(KERN_WARNING DRIVER_NAME | 640 | printk(KERN_WARNING DRIVER_NAME |
639 | ": seek does not finish after %u ms\n", tune_timeout); | 641 | ": tune timed out after %u ms\n", tune_timeout); |
640 | 642 | ||
643 | stop: | ||
641 | /* stop tuning */ | 644 | /* stop tuning */ |
642 | radio->registers[CHANNEL] &= ~CHANNEL_TUNE; | 645 | radio->registers[CHANNEL] &= ~CHANNEL_TUNE; |
643 | return si470x_set_register(radio, CHANNEL); | 646 | retval = si470x_set_register(radio, CHANNEL); |
647 | |||
648 | done: | ||
649 | return retval; | ||
644 | } | 650 | } |
645 | 651 | ||
646 | 652 | ||
@@ -731,27 +737,30 @@ static int si470x_start(struct si470x_device *radio) | |||
731 | POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM; | 737 | POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM; |
732 | retval = si470x_set_register(radio, POWERCFG); | 738 | retval = si470x_set_register(radio, POWERCFG); |
733 | if (retval < 0) | 739 | if (retval < 0) |
734 | return retval; | 740 | goto done; |
735 | 741 | ||
736 | /* sysconfig 1 */ | 742 | /* sysconfig 1 */ |
737 | radio->registers[SYSCONFIG1] = SYSCONFIG1_DE; | 743 | radio->registers[SYSCONFIG1] = SYSCONFIG1_DE; |
738 | retval = si470x_set_register(radio, SYSCONFIG1); | 744 | retval = si470x_set_register(radio, SYSCONFIG1); |
739 | if (retval < 0) | 745 | if (retval < 0) |
740 | return retval; | 746 | goto done; |
741 | 747 | ||
742 | /* sysconfig 2 */ | 748 | /* sysconfig 2 */ |
743 | radio->registers[SYSCONFIG2] = | 749 | radio->registers[SYSCONFIG2] = |
744 | (0x3f << 8) | /* SEEKTH */ | 750 | (0x3f << 8) | /* SEEKTH */ |
745 | (band << 6) | /* BAND */ | 751 | ((band << 6) & SYSCONFIG2_BAND) | /* BAND */ |
746 | (space << 4) | /* SPACE */ | 752 | ((space << 4) & SYSCONFIG2_SPACE) | /* SPACE */ |
747 | 15; /* VOLUME (max) */ | 753 | 15; /* VOLUME (max) */ |
748 | retval = si470x_set_register(radio, SYSCONFIG2); | 754 | retval = si470x_set_register(radio, SYSCONFIG2); |
749 | if (retval < 0) | 755 | if (retval < 0) |
750 | return retval; | 756 | goto done; |
751 | 757 | ||
752 | /* reset last channel */ | 758 | /* reset last channel */ |
753 | return si470x_set_chan(radio, | 759 | retval = si470x_set_chan(radio, |
754 | radio->registers[CHANNEL] & CHANNEL_CHAN); | 760 | radio->registers[CHANNEL] & CHANNEL_CHAN); |
761 | |||
762 | done: | ||
763 | return retval; | ||
755 | } | 764 | } |
756 | 765 | ||
757 | 766 | ||
@@ -766,13 +775,16 @@ static int si470x_stop(struct si470x_device *radio) | |||
766 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; | 775 | radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; |
767 | retval = si470x_set_register(radio, SYSCONFIG1); | 776 | retval = si470x_set_register(radio, SYSCONFIG1); |
768 | if (retval < 0) | 777 | if (retval < 0) |
769 | return retval; | 778 | goto done; |
770 | 779 | ||
771 | /* powercfg */ | 780 | /* powercfg */ |
772 | radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; | 781 | radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; |
773 | /* POWERCFG_ENABLE has to automatically go low */ | 782 | /* POWERCFG_ENABLE has to automatically go low */ |
774 | radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE; | 783 | radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE; |
775 | return si470x_set_register(radio, POWERCFG); | 784 | retval = si470x_set_register(radio, POWERCFG); |
785 | |||
786 | done: | ||
787 | return retval; | ||
776 | } | 788 | } |
777 | 789 | ||
778 | 790 | ||
@@ -889,6 +901,7 @@ static void si470x_work(struct work_struct *work) | |||
889 | struct si470x_device *radio = container_of(work, struct si470x_device, | 901 | struct si470x_device *radio = container_of(work, struct si470x_device, |
890 | work.work); | 902 | work.work); |
891 | 903 | ||
904 | /* safety checks */ | ||
892 | if (radio->disconnected) | 905 | if (radio->disconnected) |
893 | return; | 906 | return; |
894 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) | 907 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) |
@@ -923,11 +936,15 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
923 | 936 | ||
924 | /* block if no new data available */ | 937 | /* block if no new data available */ |
925 | while (radio->wr_index == radio->rd_index) { | 938 | while (radio->wr_index == radio->rd_index) { |
926 | if (file->f_flags & O_NONBLOCK) | 939 | if (file->f_flags & O_NONBLOCK) { |
927 | return -EWOULDBLOCK; | 940 | retval = -EWOULDBLOCK; |
941 | goto done; | ||
942 | } | ||
928 | if (wait_event_interruptible(radio->read_queue, | 943 | if (wait_event_interruptible(radio->read_queue, |
929 | radio->wr_index != radio->rd_index) < 0) | 944 | radio->wr_index != radio->rd_index) < 0) { |
930 | return -EINTR; | 945 | retval = -EINTR; |
946 | goto done; | ||
947 | } | ||
931 | } | 948 | } |
932 | 949 | ||
933 | /* calculate block count from byte count */ | 950 | /* calculate block count from byte count */ |
@@ -956,6 +973,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, | |||
956 | } | 973 | } |
957 | mutex_unlock(&radio->lock); | 974 | mutex_unlock(&radio->lock); |
958 | 975 | ||
976 | done: | ||
959 | return retval; | 977 | return retval; |
960 | } | 978 | } |
961 | 979 | ||
@@ -967,6 +985,7 @@ static unsigned int si470x_fops_poll(struct file *file, | |||
967 | struct poll_table_struct *pts) | 985 | struct poll_table_struct *pts) |
968 | { | 986 | { |
969 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 987 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
988 | int retval = 0; | ||
970 | 989 | ||
971 | /* switch on rds reception */ | 990 | /* switch on rds reception */ |
972 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { | 991 | if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { |
@@ -978,9 +997,9 @@ static unsigned int si470x_fops_poll(struct file *file, | |||
978 | poll_wait(file, &radio->read_queue, pts); | 997 | poll_wait(file, &radio->read_queue, pts); |
979 | 998 | ||
980 | if (radio->rd_index != radio->wr_index) | 999 | if (radio->rd_index != radio->wr_index) |
981 | return POLLIN | POLLRDNORM; | 1000 | retval = POLLIN | POLLRDNORM; |
982 | 1001 | ||
983 | return 0; | 1002 | return retval; |
984 | } | 1003 | } |
985 | 1004 | ||
986 | 1005 | ||
@@ -997,17 +1016,18 @@ static int si470x_fops_open(struct inode *inode, struct file *file) | |||
997 | retval = usb_autopm_get_interface(radio->intf); | 1016 | retval = usb_autopm_get_interface(radio->intf); |
998 | if (retval < 0) { | 1017 | if (retval < 0) { |
999 | radio->users--; | 1018 | radio->users--; |
1000 | return -EIO; | 1019 | retval = -EIO; |
1020 | goto done; | ||
1001 | } | 1021 | } |
1002 | 1022 | ||
1003 | if (radio->users == 1) { | 1023 | if (radio->users == 1) { |
1004 | retval = si470x_start(radio); | 1024 | retval = si470x_start(radio); |
1005 | if (retval < 0) | 1025 | if (retval < 0) |
1006 | usb_autopm_put_interface(radio->intf); | 1026 | usb_autopm_put_interface(radio->intf); |
1007 | return retval; | ||
1008 | } | 1027 | } |
1009 | 1028 | ||
1010 | return 0; | 1029 | done: |
1030 | return retval; | ||
1011 | } | 1031 | } |
1012 | 1032 | ||
1013 | 1033 | ||
@@ -1019,8 +1039,11 @@ static int si470x_fops_release(struct inode *inode, struct file *file) | |||
1019 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1039 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1020 | int retval = 0; | 1040 | int retval = 0; |
1021 | 1041 | ||
1022 | if (!radio) | 1042 | /* safety check */ |
1023 | return -ENODEV; | 1043 | if (!radio) { |
1044 | retval = -ENODEV; | ||
1045 | goto done; | ||
1046 | } | ||
1024 | 1047 | ||
1025 | mutex_lock(&radio->disconnect_lock); | 1048 | mutex_lock(&radio->disconnect_lock); |
1026 | radio->users--; | 1049 | radio->users--; |
@@ -1044,6 +1067,8 @@ static int si470x_fops_release(struct inode *inode, struct file *file) | |||
1044 | 1067 | ||
1045 | unlock: | 1068 | unlock: |
1046 | mutex_unlock(&radio->disconnect_lock); | 1069 | mutex_unlock(&radio->disconnect_lock); |
1070 | |||
1071 | done: | ||
1047 | return retval; | 1072 | return retval; |
1048 | } | 1073 | } |
1049 | 1074 | ||
@@ -1131,7 +1156,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, | |||
1131 | /* | 1156 | /* |
1132 | * si470x_vidioc_g_input - get input | 1157 | * si470x_vidioc_g_input - get input |
1133 | */ | 1158 | */ |
1134 | static int si470x_vidioc_g_input(struct file *filp, void *priv, | 1159 | static int si470x_vidioc_g_input(struct file *file, void *priv, |
1135 | unsigned int *i) | 1160 | unsigned int *i) |
1136 | { | 1161 | { |
1137 | *i = 0; | 1162 | *i = 0; |
@@ -1143,12 +1168,18 @@ static int si470x_vidioc_g_input(struct file *filp, void *priv, | |||
1143 | /* | 1168 | /* |
1144 | * si470x_vidioc_s_input - set input | 1169 | * si470x_vidioc_s_input - set input |
1145 | */ | 1170 | */ |
1146 | static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i) | 1171 | static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i) |
1147 | { | 1172 | { |
1173 | int retval = 0; | ||
1174 | |||
1175 | /* safety checks */ | ||
1148 | if (i != 0) | 1176 | if (i != 0) |
1149 | return -EINVAL; | 1177 | retval = -EINVAL; |
1150 | 1178 | ||
1151 | return 0; | 1179 | if (retval < 0) |
1180 | printk(KERN_WARNING DRIVER_NAME | ||
1181 | ": set input failed with %d\n", retval); | ||
1182 | return retval; | ||
1152 | } | 1183 | } |
1153 | 1184 | ||
1154 | 1185 | ||
@@ -1161,17 +1192,22 @@ static int si470x_vidioc_queryctrl(struct file *file, void *priv, | |||
1161 | unsigned char i; | 1192 | unsigned char i; |
1162 | int retval = -EINVAL; | 1193 | int retval = -EINVAL; |
1163 | 1194 | ||
1195 | /* safety checks */ | ||
1196 | if (!qc->id) | ||
1197 | goto done; | ||
1198 | |||
1164 | for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { | 1199 | for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { |
1165 | if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { | 1200 | if (qc->id == si470x_v4l2_queryctrl[i].id) { |
1166 | memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); | 1201 | memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); |
1167 | retval = 0; | 1202 | retval = 0; |
1168 | break; | 1203 | break; |
1169 | } | 1204 | } |
1170 | } | 1205 | } |
1206 | |||
1207 | done: | ||
1171 | if (retval < 0) | 1208 | if (retval < 0) |
1172 | printk(KERN_WARNING DRIVER_NAME | 1209 | printk(KERN_WARNING DRIVER_NAME |
1173 | ": query control failed with %d\n", retval); | 1210 | ": query controls failed with %d\n", retval); |
1174 | |||
1175 | return retval; | 1211 | return retval; |
1176 | } | 1212 | } |
1177 | 1213 | ||
@@ -1183,9 +1219,13 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, | |||
1183 | struct v4l2_control *ctrl) | 1219 | struct v4l2_control *ctrl) |
1184 | { | 1220 | { |
1185 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1221 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1222 | int retval = 0; | ||
1186 | 1223 | ||
1187 | if (radio->disconnected) | 1224 | /* safety checks */ |
1188 | return -EIO; | 1225 | if (radio->disconnected) { |
1226 | retval = -EIO; | ||
1227 | goto done; | ||
1228 | } | ||
1189 | 1229 | ||
1190 | switch (ctrl->id) { | 1230 | switch (ctrl->id) { |
1191 | case V4L2_CID_AUDIO_VOLUME: | 1231 | case V4L2_CID_AUDIO_VOLUME: |
@@ -1196,9 +1236,15 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, | |||
1196 | ctrl->value = ((radio->registers[POWERCFG] & | 1236 | ctrl->value = ((radio->registers[POWERCFG] & |
1197 | POWERCFG_DMUTE) == 0) ? 1 : 0; | 1237 | POWERCFG_DMUTE) == 0) ? 1 : 0; |
1198 | break; | 1238 | break; |
1239 | default: | ||
1240 | retval = -EINVAL; | ||
1199 | } | 1241 | } |
1200 | 1242 | ||
1201 | return 0; | 1243 | done: |
1244 | if (retval < 0) | ||
1245 | printk(KERN_WARNING DRIVER_NAME | ||
1246 | ": get control failed with %d\n", retval); | ||
1247 | return retval; | ||
1202 | } | 1248 | } |
1203 | 1249 | ||
1204 | 1250 | ||
@@ -1209,10 +1255,13 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | |||
1209 | struct v4l2_control *ctrl) | 1255 | struct v4l2_control *ctrl) |
1210 | { | 1256 | { |
1211 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1257 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1212 | int retval; | 1258 | int retval = 0; |
1213 | 1259 | ||
1214 | if (radio->disconnected) | 1260 | /* safety checks */ |
1215 | return -EIO; | 1261 | if (radio->disconnected) { |
1262 | retval = -EIO; | ||
1263 | goto done; | ||
1264 | } | ||
1216 | 1265 | ||
1217 | switch (ctrl->id) { | 1266 | switch (ctrl->id) { |
1218 | case V4L2_CID_AUDIO_VOLUME: | 1267 | case V4L2_CID_AUDIO_VOLUME: |
@@ -1230,10 +1279,11 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | |||
1230 | default: | 1279 | default: |
1231 | retval = -EINVAL; | 1280 | retval = -EINVAL; |
1232 | } | 1281 | } |
1282 | |||
1283 | done: | ||
1233 | if (retval < 0) | 1284 | if (retval < 0) |
1234 | printk(KERN_WARNING DRIVER_NAME | 1285 | printk(KERN_WARNING DRIVER_NAME |
1235 | ": set control failed with %d\n", retval); | 1286 | ": set control failed with %d\n", retval); |
1236 | |||
1237 | return retval; | 1287 | return retval; |
1238 | } | 1288 | } |
1239 | 1289 | ||
@@ -1244,13 +1294,22 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, | |||
1244 | static int si470x_vidioc_g_audio(struct file *file, void *priv, | 1294 | static int si470x_vidioc_g_audio(struct file *file, void *priv, |
1245 | struct v4l2_audio *audio) | 1295 | struct v4l2_audio *audio) |
1246 | { | 1296 | { |
1247 | if (audio->index > 1) | 1297 | int retval = 0; |
1248 | return -EINVAL; | 1298 | |
1299 | /* safety checks */ | ||
1300 | if (audio->index != 0) { | ||
1301 | retval = -EINVAL; | ||
1302 | goto done; | ||
1303 | } | ||
1249 | 1304 | ||
1250 | strcpy(audio->name, "Radio"); | 1305 | strcpy(audio->name, "Radio"); |
1251 | audio->capability = V4L2_AUDCAP_STEREO; | 1306 | audio->capability = V4L2_AUDCAP_STEREO; |
1252 | 1307 | ||
1253 | return 0; | 1308 | done: |
1309 | if (retval < 0) | ||
1310 | printk(KERN_WARNING DRIVER_NAME | ||
1311 | ": get audio failed with %d\n", retval); | ||
1312 | return retval; | ||
1254 | } | 1313 | } |
1255 | 1314 | ||
1256 | 1315 | ||
@@ -1260,10 +1319,19 @@ static int si470x_vidioc_g_audio(struct file *file, void *priv, | |||
1260 | static int si470x_vidioc_s_audio(struct file *file, void *priv, | 1319 | static int si470x_vidioc_s_audio(struct file *file, void *priv, |
1261 | struct v4l2_audio *audio) | 1320 | struct v4l2_audio *audio) |
1262 | { | 1321 | { |
1263 | if (audio->index != 0) | 1322 | int retval = 0; |
1264 | return -EINVAL; | ||
1265 | 1323 | ||
1266 | return 0; | 1324 | /* safety checks */ |
1325 | if (audio->index != 0) { | ||
1326 | retval = -EINVAL; | ||
1327 | goto done; | ||
1328 | } | ||
1329 | |||
1330 | done: | ||
1331 | if (retval < 0) | ||
1332 | printk(KERN_WARNING DRIVER_NAME | ||
1333 | ": set audio failed with %d\n", retval); | ||
1334 | return retval; | ||
1267 | } | 1335 | } |
1268 | 1336 | ||
1269 | 1337 | ||
@@ -1274,20 +1342,23 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
1274 | struct v4l2_tuner *tuner) | 1342 | struct v4l2_tuner *tuner) |
1275 | { | 1343 | { |
1276 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1344 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1277 | int retval; | 1345 | int retval = 0; |
1278 | 1346 | ||
1279 | if (radio->disconnected) | 1347 | /* safety checks */ |
1280 | return -EIO; | 1348 | if (radio->disconnected) { |
1281 | if (tuner->index > 0) | 1349 | retval = -EIO; |
1282 | return -EINVAL; | 1350 | goto done; |
1351 | } | ||
1352 | if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { | ||
1353 | retval = -EINVAL; | ||
1354 | goto done; | ||
1355 | } | ||
1283 | 1356 | ||
1284 | /* read status rssi */ | ||
1285 | retval = si470x_get_register(radio, STATUSRSSI); | 1357 | retval = si470x_get_register(radio, STATUSRSSI); |
1286 | if (retval < 0) | 1358 | if (retval < 0) |
1287 | return retval; | 1359 | goto done; |
1288 | 1360 | ||
1289 | strcpy(tuner->name, "FM"); | 1361 | strcpy(tuner->name, "FM"); |
1290 | tuner->type = V4L2_TUNER_RADIO; | ||
1291 | switch (band) { | 1362 | switch (band) { |
1292 | /* 0: 87.5 - 108 MHz (USA, Europe, default) */ | 1363 | /* 0: 87.5 - 108 MHz (USA, Europe, default) */ |
1293 | default: | 1364 | default: |
@@ -1321,7 +1392,11 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, | |||
1321 | /* automatic frequency control: -1: freq to low, 1 freq to high */ | 1392 | /* automatic frequency control: -1: freq to low, 1 freq to high */ |
1322 | tuner->afc = 0; | 1393 | tuner->afc = 0; |
1323 | 1394 | ||
1324 | return 0; | 1395 | done: |
1396 | if (retval < 0) | ||
1397 | printk(KERN_WARNING DRIVER_NAME | ||
1398 | ": get tuner failed with %d\n", retval); | ||
1399 | return retval; | ||
1325 | } | 1400 | } |
1326 | 1401 | ||
1327 | 1402 | ||
@@ -1332,12 +1407,17 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
1332 | struct v4l2_tuner *tuner) | 1407 | struct v4l2_tuner *tuner) |
1333 | { | 1408 | { |
1334 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1409 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1335 | int retval; | 1410 | int retval = 0; |
1336 | 1411 | ||
1337 | if (radio->disconnected) | 1412 | /* safety checks */ |
1338 | return -EIO; | 1413 | if (radio->disconnected) { |
1339 | if (tuner->index > 0) | 1414 | retval = -EIO; |
1340 | return -EINVAL; | 1415 | goto done; |
1416 | } | ||
1417 | if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { | ||
1418 | retval = -EINVAL; | ||
1419 | goto done; | ||
1420 | } | ||
1341 | 1421 | ||
1342 | if (tuner->audmode == V4L2_TUNER_MODE_MONO) | 1422 | if (tuner->audmode == V4L2_TUNER_MODE_MONO) |
1343 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ | 1423 | radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ |
@@ -1345,10 +1425,11 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, | |||
1345 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ | 1425 | radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ |
1346 | 1426 | ||
1347 | retval = si470x_set_register(radio, POWERCFG); | 1427 | retval = si470x_set_register(radio, POWERCFG); |
1428 | |||
1429 | done: | ||
1348 | if (retval < 0) | 1430 | if (retval < 0) |
1349 | printk(KERN_WARNING DRIVER_NAME | 1431 | printk(KERN_WARNING DRIVER_NAME |
1350 | ": set tuner failed with %d\n", retval); | 1432 | ": set tuner failed with %d\n", retval); |
1351 | |||
1352 | return retval; | 1433 | return retval; |
1353 | } | 1434 | } |
1354 | 1435 | ||
@@ -1360,12 +1441,25 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, | |||
1360 | struct v4l2_frequency *freq) | 1441 | struct v4l2_frequency *freq) |
1361 | { | 1442 | { |
1362 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1443 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1444 | int retval = 0; | ||
1363 | 1445 | ||
1364 | if (radio->disconnected) | 1446 | /* safety checks */ |
1365 | return -EIO; | 1447 | if (radio->disconnected) { |
1448 | retval = -EIO; | ||
1449 | goto done; | ||
1450 | } | ||
1451 | if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { | ||
1452 | retval = -EINVAL; | ||
1453 | goto done; | ||
1454 | } | ||
1455 | |||
1456 | retval = si470x_get_freq(radio, &freq->frequency); | ||
1366 | 1457 | ||
1367 | freq->type = V4L2_TUNER_RADIO; | 1458 | done: |
1368 | return si470x_get_freq(radio, &radio->frequency); | 1459 | if (retval < 0) |
1460 | printk(KERN_WARNING DRIVER_NAME | ||
1461 | ": get frequency failed with %d\n", retval); | ||
1462 | return retval; | ||
1369 | } | 1463 | } |
1370 | 1464 | ||
1371 | 1465 | ||
@@ -1376,19 +1470,25 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, | |||
1376 | struct v4l2_frequency *freq) | 1470 | struct v4l2_frequency *freq) |
1377 | { | 1471 | { |
1378 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); | 1472 | struct si470x_device *radio = video_get_drvdata(video_devdata(file)); |
1379 | int retval; | 1473 | int retval = 0; |
1380 | 1474 | ||
1381 | if (radio->disconnected) | 1475 | /* safety checks */ |
1382 | return -EIO; | 1476 | if (radio->disconnected) { |
1383 | if (freq->type != V4L2_TUNER_RADIO) | 1477 | retval = -EIO; |
1384 | return -EINVAL; | 1478 | goto done; |
1479 | } | ||
1480 | if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { | ||
1481 | retval = -EINVAL; | ||
1482 | goto done; | ||
1483 | } | ||
1385 | 1484 | ||
1386 | retval = si470x_set_freq(radio, freq->frequency); | 1485 | retval = si470x_set_freq(radio, freq->frequency); |
1486 | |||
1487 | done: | ||
1387 | if (retval < 0) | 1488 | if (retval < 0) |
1388 | printk(KERN_WARNING DRIVER_NAME | 1489 | printk(KERN_WARNING DRIVER_NAME |
1389 | ": set frequency failed with %d\n", retval); | 1490 | ": set frequency failed with %d\n", retval); |
1390 | 1491 | return retval; | |
1391 | return 0; | ||
1392 | } | 1492 | } |
1393 | 1493 | ||
1394 | 1494 | ||
@@ -1428,33 +1528,36 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
1428 | const struct usb_device_id *id) | 1528 | const struct usb_device_id *id) |
1429 | { | 1529 | { |
1430 | struct si470x_device *radio; | 1530 | struct si470x_device *radio; |
1431 | int retval = -ENOMEM; | 1531 | int retval = 0; |
1432 | 1532 | ||
1433 | /* private data allocation */ | 1533 | /* private data allocation and initialization */ |
1434 | radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); | 1534 | radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); |
1435 | if (!radio) | 1535 | if (!radio) { |
1536 | retval = -ENOMEM; | ||
1436 | goto err_initial; | 1537 | goto err_initial; |
1437 | 1538 | } | |
1438 | /* video device allocation */ | ||
1439 | radio->videodev = video_device_alloc(); | ||
1440 | if (!radio->videodev) | ||
1441 | goto err_radio; | ||
1442 | |||
1443 | /* initial configuration */ | ||
1444 | memcpy(radio->videodev, &si470x_viddev_template, | ||
1445 | sizeof(si470x_viddev_template)); | ||
1446 | radio->users = 0; | 1539 | radio->users = 0; |
1447 | radio->disconnected = 0; | 1540 | radio->disconnected = 0; |
1448 | radio->usbdev = interface_to_usbdev(intf); | 1541 | radio->usbdev = interface_to_usbdev(intf); |
1449 | radio->intf = intf; | 1542 | radio->intf = intf; |
1450 | mutex_init(&radio->disconnect_lock); | 1543 | mutex_init(&radio->disconnect_lock); |
1451 | mutex_init(&radio->lock); | 1544 | mutex_init(&radio->lock); |
1545 | |||
1546 | /* video device allocation and initialization */ | ||
1547 | radio->videodev = video_device_alloc(); | ||
1548 | if (!radio->videodev) { | ||
1549 | retval = -ENOMEM; | ||
1550 | goto err_radio; | ||
1551 | } | ||
1552 | memcpy(radio->videodev, &si470x_viddev_template, | ||
1553 | sizeof(si470x_viddev_template)); | ||
1452 | video_set_drvdata(radio->videodev, radio); | 1554 | video_set_drvdata(radio->videodev, radio); |
1453 | 1555 | ||
1454 | /* show some infos about the specific device */ | 1556 | /* show some infos about the specific device */ |
1455 | retval = -EIO; | 1557 | if (si470x_get_all_registers(radio) < 0) { |
1456 | if (si470x_get_all_registers(radio) < 0) | 1558 | retval = -EIO; |
1457 | goto err_all; | 1559 | goto err_all; |
1560 | } | ||
1458 | printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", | 1561 | printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", |
1459 | radio->registers[DEVICEID], radio->registers[CHIPID]); | 1562 | radio->registers[DEVICEID], radio->registers[CHIPID]); |
1460 | 1563 | ||
@@ -1480,8 +1583,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
1480 | /* rds buffer allocation */ | 1583 | /* rds buffer allocation */ |
1481 | radio->buf_size = rds_buf * 3; | 1584 | radio->buf_size = rds_buf * 3; |
1482 | radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); | 1585 | radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); |
1483 | if (!radio->buffer) | 1586 | if (!radio->buffer) { |
1587 | retval = -EIO; | ||
1484 | goto err_all; | 1588 | goto err_all; |
1589 | } | ||
1485 | 1590 | ||
1486 | /* rds buffer configuration */ | 1591 | /* rds buffer configuration */ |
1487 | radio->wr_index = 0; | 1592 | radio->wr_index = 0; |
@@ -1493,6 +1598,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, | |||
1493 | 1598 | ||
1494 | /* register video device */ | 1599 | /* register video device */ |
1495 | if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { | 1600 | if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { |
1601 | retval = -EIO; | ||
1496 | printk(KERN_WARNING DRIVER_NAME | 1602 | printk(KERN_WARNING DRIVER_NAME |
1497 | ": Could not register video device\n"); | 1603 | ": Could not register video device\n"); |
1498 | goto err_all; | 1604 | goto err_all; |