aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-01-05 15:22:01 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:04:34 -0500
commit0be4375410f1ecc917f3c0caf8f98908d357c93f (patch)
tree1ec68f3804fccd515edc00b557ae8b8e80fd9584 /drivers/media/video/em28xx
parent3abee53e4402b6ae39e1e610f9ef94eb74097138 (diff)
V4L/DVB (6956): Add Radio support for em28xx
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c296
-rw-r--r--drivers/media/video/em28xx/em28xx.h2
2 files changed, 238 insertions, 60 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 0f075f532eae..5a90462d82e5 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -61,13 +61,17 @@ static LIST_HEAD(em28xx_devlist);
61 61
62static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 62static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
63static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 63static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
64static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; 64static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
65static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET };
66
65module_param_array(card, int, NULL, 0444); 67module_param_array(card, int, NULL, 0444);
66module_param_array(video_nr, int, NULL, 0444); 68module_param_array(video_nr, int, NULL, 0444);
67module_param_array(vbi_nr, int, NULL, 0444); 69module_param_array(vbi_nr, int, NULL, 0444);
68MODULE_PARM_DESC(card,"card type"); 70module_param_array(radio_nr, int, NULL, 0444);
69MODULE_PARM_DESC(video_nr,"video device numbers"); 71MODULE_PARM_DESC(card, "card type");
70MODULE_PARM_DESC(vbi_nr,"vbi device numbers"); 72MODULE_PARM_DESC(video_nr, "video device numbers");
73MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
74MODULE_PARM_DESC(radio_nr, "radio device numbers");
71 75
72static unsigned int video_debug = 0; 76static unsigned int video_debug = 0;
73module_param(video_debug,int,0644); 77module_param(video_debug,int,0644);
@@ -791,7 +795,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
791 struct em28xx_fh *fh = priv; 795 struct em28xx_fh *fh = priv;
792 struct em28xx *dev = fh->dev; 796 struct em28xx *dev = fh->dev;
793 797
794 f->type = V4L2_TUNER_ANALOG_TV; 798 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
795 f->frequency = dev->ctl_freq; 799 f->frequency = dev->ctl_freq;
796 800
797 return 0; 801 return 0;
@@ -811,7 +815,9 @@ static int vidioc_s_frequency(struct file *file, void *priv,
811 if (0 != f->tuner) 815 if (0 != f->tuner)
812 return -EINVAL; 816 return -EINVAL;
813 817
814 if (V4L2_TUNER_ANALOG_TV != f->type) 818 if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV))
819 return -EINVAL;
820 if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO))
815 return -EINVAL; 821 return -EINVAL;
816 822
817 mutex_lock(&dev->lock); 823 mutex_lock(&dev->lock);
@@ -1148,6 +1154,102 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1148 return 0; 1154 return 0;
1149} 1155}
1150 1156
1157/* ----------------------------------------------------------- */
1158/* RADIO ESPECIFIC IOCTLS */
1159/* ----------------------------------------------------------- */
1160
1161static int radio_querycap(struct file *file, void *priv,
1162 struct v4l2_capability *cap)
1163{
1164 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1165
1166 strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
1167 strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
1168 strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info));
1169
1170 cap->version = EM28XX_VERSION_CODE;
1171 cap->capabilities = V4L2_CAP_TUNER;
1172 return 0;
1173}
1174
1175static int radio_g_tuner(struct file *file, void *priv,
1176 struct v4l2_tuner *t)
1177{
1178 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1179
1180 if (unlikely(t->index > 0))
1181 return -EINVAL;
1182
1183 strcpy(t->name, "Radio");
1184 t->type = V4L2_TUNER_RADIO;
1185
1186 em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
1187 return 0;
1188}
1189
1190static int radio_enum_input(struct file *file, void *priv,
1191 struct v4l2_input *i)
1192{
1193 if (i->index != 0)
1194 return -EINVAL;
1195 strcpy(i->name, "Radio");
1196 i->type = V4L2_INPUT_TYPE_TUNER;
1197
1198 return 0;
1199}
1200
1201static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1202{
1203 if (unlikely(a->index))
1204 return -EINVAL;
1205
1206 strcpy(a->name, "Radio");
1207 return 0;
1208}
1209
1210static int radio_s_tuner(struct file *file, void *priv,
1211 struct v4l2_tuner *t)
1212{
1213 struct em28xx *dev = ((struct em28xx_fh *)priv)->dev;
1214
1215 if (0 != t->index)
1216 return -EINVAL;
1217
1218 em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
1219
1220 return 0;
1221}
1222
1223static int radio_s_audio(struct file *file, void *fh,
1224 struct v4l2_audio *a)
1225{
1226 return 0;
1227}
1228
1229static int radio_s_input(struct file *file, void *fh, unsigned int i)
1230{
1231 return 0;
1232}
1233
1234static int radio_queryctrl(struct file *file, void *priv,
1235 struct v4l2_queryctrl *qc)
1236{
1237 int i;
1238
1239 if (qc->id < V4L2_CID_BASE ||
1240 qc->id >= V4L2_CID_LASTP1)
1241 return -EINVAL;
1242
1243 for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
1244 if (qc->id && qc->id == em28xx_qctrl[i].id) {
1245 memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc));
1246 return 0;
1247 }
1248 }
1249
1250 return -EINVAL;
1251}
1252
1151/* 1253/*
1152 * em28xx_v4l2_open() 1254 * em28xx_v4l2_open()
1153 * inits the device and starts isoc transfer 1255 * inits the device and starts isoc transfer
@@ -1155,7 +1257,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1155static int em28xx_v4l2_open(struct inode *inode, struct file *filp) 1257static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1156{ 1258{
1157 int minor = iminor(inode); 1259 int minor = iminor(inode);
1158 int errCode = 0; 1260 int errCode = 0, radio = 0;
1159 struct em28xx *h,*dev = NULL; 1261 struct em28xx *h,*dev = NULL;
1160 struct em28xx_fh *fh; 1262 struct em28xx_fh *fh;
1161 1263
@@ -1168,6 +1270,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1168 dev = h; 1270 dev = h;
1169 dev->type = V4L2_BUF_TYPE_VBI_CAPTURE; 1271 dev->type = V4L2_BUF_TYPE_VBI_CAPTURE;
1170 } 1272 }
1273 if (h->radio_dev &&
1274 h->radio_dev->minor == minor) {
1275 radio = 1;
1276 dev = h;
1277 }
1171 } 1278 }
1172 if (NULL == dev) 1279 if (NULL == dev)
1173 return -ENODEV; 1280 return -ENODEV;
@@ -1183,6 +1290,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1183 } 1290 }
1184 mutex_lock(&dev->lock); 1291 mutex_lock(&dev->lock);
1185 fh->dev = dev; 1292 fh->dev = dev;
1293 fh->radio = radio;
1186 filp->private_data = fh; 1294 filp->private_data = fh;
1187 1295
1188 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { 1296 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
@@ -1207,6 +1315,10 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
1207 1315
1208 em28xx_empty_framequeues(dev); 1316 em28xx_empty_framequeues(dev);
1209 } 1317 }
1318 if (fh->radio) {
1319 em28xx_videodbg("video_open: setting radio device\n");
1320 em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
1321 }
1210 1322
1211 dev->users++; 1323 dev->users++;
1212 1324
@@ -1229,12 +1341,30 @@ static void em28xx_release_resources(struct em28xx *dev)
1229 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, 1341 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
1230 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); 1342 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
1231 list_del(&dev->devlist); 1343 list_del(&dev->devlist);
1232 video_unregister_device(dev->vdev); 1344 if (dev->radio_dev) {
1233 video_unregister_device(dev->vbi_dev); 1345 if (-1 != dev->radio_dev->minor)
1346 video_unregister_device(dev->radio_dev);
1347 else
1348 video_device_release(dev->radio_dev);
1349 dev->radio_dev = NULL;
1350 }
1351 if (dev->vbi_dev) {
1352 if (-1 != dev->vbi_dev->minor)
1353 video_unregister_device(dev->vbi_dev);
1354 else
1355 video_device_release(dev->vbi_dev);
1356 dev->vbi_dev = NULL;
1357 }
1358 if (dev->vdev) {
1359 if (-1 != dev->vdev->minor)
1360 video_unregister_device(dev->vdev);
1361 else
1362 video_device_release(dev->vdev);
1363 dev->vdev = NULL;
1364 }
1234 em28xx_i2c_unregister(dev); 1365 em28xx_i2c_unregister(dev);
1235 usb_put_dev(dev->udev); 1366 usb_put_dev(dev->udev);
1236 1367
1237
1238 /* Mark device as unused */ 1368 /* Mark device as unused */
1239 em28xx_devused&=~(1<<dev->devno); 1369 em28xx_devused&=~(1<<dev->devno);
1240} 1370}
@@ -1555,6 +1685,15 @@ static const struct file_operations em28xx_v4l_fops = {
1555 .compat_ioctl = v4l_compat_ioctl32, 1685 .compat_ioctl = v4l_compat_ioctl32,
1556}; 1686};
1557 1687
1688static const struct file_operations radio_fops = {
1689 .owner = THIS_MODULE,
1690 .open = em28xx_v4l2_open,
1691 .release = em28xx_v4l2_close,
1692 .ioctl = video_ioctl2,
1693 .compat_ioctl = v4l_compat_ioctl32,
1694 .llseek = no_llseek,
1695};
1696
1558static const struct video_device em28xx_video_template = { 1697static const struct video_device em28xx_video_template = {
1559 .fops = &em28xx_v4l_fops, 1698 .fops = &em28xx_v4l_fops,
1560 .release = video_device_release, 1699 .release = video_device_release,
@@ -1595,6 +1734,25 @@ static const struct video_device em28xx_video_template = {
1595 .current_norm = V4L2_STD_PAL, 1734 .current_norm = V4L2_STD_PAL,
1596}; 1735};
1597 1736
1737static struct video_device em28xx_radio_template = {
1738 .name = "em28xx-radio",
1739 .type = VID_TYPE_TUNER,
1740 .fops = &radio_fops,
1741 .minor = -1,
1742 .vidioc_querycap = radio_querycap,
1743 .vidioc_g_tuner = radio_g_tuner,
1744 .vidioc_enum_input = radio_enum_input,
1745 .vidioc_g_audio = radio_g_audio,
1746 .vidioc_s_tuner = radio_s_tuner,
1747 .vidioc_s_audio = radio_s_audio,
1748 .vidioc_s_input = radio_s_input,
1749 .vidioc_queryctrl = radio_queryctrl,
1750 .vidioc_g_ctrl = vidioc_g_ctrl,
1751 .vidioc_s_ctrl = vidioc_s_ctrl,
1752 .vidioc_g_frequency = vidioc_g_frequency,
1753 .vidioc_s_frequency = vidioc_s_frequency,
1754};
1755
1598/******************************** usb interface *****************************************/ 1756/******************************** usb interface *****************************************/
1599 1757
1600 1758
@@ -1637,6 +1795,29 @@ void em28xx_unregister_extension(struct em28xx_ops *ops)
1637} 1795}
1638EXPORT_SYMBOL(em28xx_unregister_extension); 1796EXPORT_SYMBOL(em28xx_unregister_extension);
1639 1797
1798struct video_device *em28xx_vdev_init(struct em28xx *dev,
1799 const struct video_device *template,
1800 const int type,
1801 const char *type_name)
1802{
1803 struct video_device *vfd;
1804
1805 vfd = video_device_alloc();
1806 if (NULL == vfd)
1807 return NULL;
1808 *vfd = *template;
1809 vfd->minor = -1;
1810 vfd->dev = &dev->udev->dev;
1811 vfd->release = video_device_release;
1812 vfd->type = type;
1813
1814 snprintf(vfd->name, sizeof(vfd->name), "%s %s",
1815 dev->name, type_name);
1816
1817 return vfd;
1818}
1819
1820
1640/* 1821/*
1641 * em28xx_init_dev() 1822 * em28xx_init_dev()
1642 * allocates and inits the device structs, registers i2c bus and v4l device 1823 * allocates and inits the device structs, registers i2c bus and v4l device
@@ -1710,40 +1891,55 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1710 1891
1711 errCode = em28xx_config(dev); 1892 errCode = em28xx_config(dev);
1712 1893
1894 list_add_tail(&dev->devlist, &em28xx_devlist);
1895
1713 /* allocate and fill video video_device struct */ 1896 /* allocate and fill video video_device struct */
1714 dev->vdev = video_device_alloc(); 1897 dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template,
1898 VID_TYPE_CAPTURE, "video");
1715 if (NULL == dev->vdev) { 1899 if (NULL == dev->vdev) {
1716 em28xx_errdev("cannot allocate video_device.\n"); 1900 em28xx_errdev("cannot allocate video_device.\n");
1717 em28xx_devused&=~(1<<dev->devno); 1901 goto fail_unreg;
1718 kfree(dev);
1719 return -ENOMEM;
1720 } 1902 }
1721 memcpy(dev->vdev, &em28xx_video_template,
1722 sizeof(em28xx_video_template));
1723 dev->vdev->type = VID_TYPE_CAPTURE;
1724 if (dev->has_tuner) 1903 if (dev->has_tuner)
1725 dev->vdev->type |= VID_TYPE_TUNER; 1904 dev->vdev->type |= VID_TYPE_TUNER;
1726 dev->vdev->dev = &dev->udev->dev; 1905
1727 snprintf(dev->vdev->name, sizeof(dev->vbi_dev->name), 1906 /* register v4l2 video video_device */
1728 "%s#%d %s", "em28xx", dev->devno, "video"); 1907 retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
1908 video_nr[dev->devno]);
1909 if (retval) {
1910 em28xx_errdev("unable to register video device (error=%i).\n",
1911 retval);
1912 goto fail_unreg;
1913 }
1729 1914
1730 /* Allocate and fill vbi video_device struct */ 1915 /* Allocate and fill vbi video_device struct */
1731 dev->vbi_dev = video_device_alloc(); 1916 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
1732 if (NULL == dev->vbi_dev) { 1917 VFL_TYPE_VBI, "vbi");
1733 em28xx_errdev("cannot allocate video_device.\n"); 1918 /* register v4l2 vbi video_device */
1734 kfree(dev->vdev); 1919 if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
1735 em28xx_devused&=~(1<<dev->devno); 1920 vbi_nr[dev->devno]) < 0) {
1736 kfree(dev); 1921 em28xx_errdev("unable to register vbi device\n");
1737 return -ENOMEM; 1922 retval = -ENODEV;
1923 goto fail_unreg;
1924 }
1925
1926 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
1927 dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
1928 VFL_TYPE_RADIO, "radio");
1929 if (NULL == dev->radio_dev) {
1930 em28xx_errdev("cannot allocate video_device.\n");
1931 goto fail_unreg;
1932 }
1933 retval = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
1934 radio_nr[dev->devno]);
1935 if (retval < 0) {
1936 em28xx_errdev("can't register radio device\n");
1937 goto fail_unreg;
1938 }
1939 em28xx_info("Registered radio device as /dev/radio%d\n",
1940 dev->radio_dev->minor & 0x1f);
1738 } 1941 }
1739 memcpy(dev->vbi_dev, &em28xx_video_template,
1740 sizeof(em28xx_video_template));
1741 dev->vbi_dev->type = VFL_TYPE_VBI;
1742 dev->vbi_dev->dev = &dev->udev->dev;
1743 snprintf(dev->vbi_dev->name, sizeof(dev->vbi_dev->name),
1744 "%s#%d %s", "em28xx", dev->devno, "vbi");
1745 1942
1746 list_add_tail(&dev->devlist,&em28xx_devlist);
1747 1943
1748 if (dev->has_msp34xx) { 1944 if (dev->has_msp34xx) {
1749 /* Send a reset to other chips via gpio */ 1945 /* Send a reset to other chips via gpio */
@@ -1755,32 +1951,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1755 1951
1756 video_mux(dev, 0); 1952 video_mux(dev, 0);
1757 1953
1758 /* register v4l2 video video_device */
1759 if ((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER,
1760 video_nr[dev->devno]))) {
1761 em28xx_errdev("unable to register video device (error=%i).\n",
1762 retval);
1763 mutex_unlock(&dev->lock);
1764 list_del(&dev->devlist);
1765 video_device_release(dev->vdev);
1766 em28xx_devused&=~(1<<dev->devno);
1767 kfree(dev);
1768 return -ENODEV;
1769 }
1770
1771 /* register v4l2 vbi video_device */
1772 if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
1773 vbi_nr[dev->devno]) < 0) {
1774 printk("unable to register vbi device\n");
1775 mutex_unlock(&dev->lock);
1776 list_del(&dev->devlist);
1777 video_device_release(dev->vbi_dev);
1778 video_device_release(dev->vdev);
1779 em28xx_devused&=~(1<<dev->devno);
1780 kfree(dev);
1781 return -ENODEV;
1782 }
1783
1784 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", 1954 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n",
1785 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, 1955 dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN,
1786 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); 1956 dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN);
@@ -1795,6 +1965,12 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1795 mutex_unlock(&em28xx_extension_devlist_lock); 1965 mutex_unlock(&em28xx_extension_devlist_lock);
1796 1966
1797 return 0; 1967 return 0;
1968
1969fail_unreg:
1970 em28xx_release_resources(dev);
1971 mutex_unlock(&dev->lock);
1972 kfree(dev);
1973 return retval;
1798} 1974}
1799 1975
1800#if defined(CONFIG_MODULES) && defined(MODULE) 1976#if defined(CONFIG_MODULES) && defined(MODULE)
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 2d57330c4537..2ba34e5b4cc2 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -191,6 +191,7 @@ struct em28xx_board {
191 enum em28xx_decoder decoder; 191 enum em28xx_decoder decoder;
192 192
193 struct em28xx_input input[MAX_EM28XX_INPUT]; 193 struct em28xx_input input[MAX_EM28XX_INPUT];
194 struct em28xx_input radio;
194}; 195};
195 196
196struct em28xx_eeprom { 197struct em28xx_eeprom {
@@ -307,6 +308,7 @@ struct em28xx {
307 struct list_head inqueue, outqueue; 308 struct list_head inqueue, outqueue;
308 wait_queue_head_t open, wait_frame, wait_stream; 309 wait_queue_head_t open, wait_frame, wait_stream;
309 struct video_device *vbi_dev; 310 struct video_device *vbi_dev;
311 struct video_device *radio_dev;
310 312
311 unsigned char eedata[256]; 313 unsigned char eedata[256];
312 314