aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-03-18 12:16:44 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:30 -0400
commit8bcfd7af902eaa7c0029082247fe0682ce0c1a5b (patch)
tree8f3fdd9eaf3fb4608dbf97b6c83dd259ec99db7d /drivers/media/video
parent21508b902b314e0cd9c081a9141b138e96c9f441 (diff)
V4L/DVB (11115): cafe_ccic: use v4l2_subdev to talk to the ov7670 sensor.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Acked-by: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/cafe_ccic.c106
1 files changed, 32 insertions, 74 deletions
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 600dde379efe..3363e501d6d7 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -148,7 +148,8 @@ struct cafe_camera
148 struct pci_dev *pdev; 148 struct pci_dev *pdev;
149 struct video_device vdev; 149 struct video_device vdev;
150 struct i2c_adapter i2c_adapter; 150 struct i2c_adapter i2c_adapter;
151 struct i2c_client *sensor; 151 struct v4l2_subdev *sensor;
152 unsigned short sensor_addr;
152 153
153 unsigned char __iomem *regs; 154 unsigned char __iomem *regs;
154 struct list_head dev_list; /* link to other devices */ 155 struct list_head dev_list; /* link to other devices */
@@ -196,6 +197,8 @@ struct cafe_camera
196#define CF_DMA_ACTIVE 3 /* A frame is incoming */ 197#define CF_DMA_ACTIVE 3 /* A frame is incoming */
197#define CF_CONFIG_NEEDED 4 /* Must configure hardware */ 198#define CF_CONFIG_NEEDED 4 /* Must configure hardware */
198 199
200#define sensor_call(cam, o, f, args...) \
201 v4l2_subdev_call(cam->sensor, o, f, ##args)
199 202
200static inline struct cafe_camera *to_cam(struct v4l2_device *dev) 203static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
201{ 204{
@@ -440,14 +443,6 @@ static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
440 int ret = -EINVAL; 443 int ret = -EINVAL;
441 444
442 /* 445 /*
443 * Refuse to talk to anything but OV cam chips. We should
444 * never even see an attempt to do so, but one never knows.
445 */
446 if (cam->sensor && addr != cam->sensor->addr) {
447 cam_err(cam, "funky smbus addr %d\n", addr);
448 return -EINVAL;
449 }
450 /*
451 * This interface would appear to only do byte data ops. OK 446 * This interface would appear to only do byte data ops. OK
452 * it can do word too, but the cam chip has no use for that. 447 * it can do word too, but the cam chip has no use for that.
453 */ 448 */
@@ -485,40 +480,9 @@ static struct i2c_algorithm cafe_smbus_algo = {
485}; 480};
486 481
487/* Somebody is on the bus */ 482/* Somebody is on the bus */
488static int cafe_cam_init(struct cafe_camera *cam);
489static void cafe_ctlr_stop_dma(struct cafe_camera *cam); 483static void cafe_ctlr_stop_dma(struct cafe_camera *cam);
490static void cafe_ctlr_power_down(struct cafe_camera *cam); 484static void cafe_ctlr_power_down(struct cafe_camera *cam);
491 485
492static int cafe_smbus_attach(struct i2c_client *client)
493{
494 struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
495 struct cafe_camera *cam = to_cam(v4l2_dev);
496
497 /*
498 * Don't talk to chips we don't recognize.
499 */
500 if (client->driver->id == I2C_DRIVERID_OV7670) {
501 cam->sensor = client;
502 return cafe_cam_init(cam);
503 }
504 return -EINVAL;
505}
506
507static int cafe_smbus_detach(struct i2c_client *client)
508{
509 struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
510 struct cafe_camera *cam = to_cam(v4l2_dev);
511
512 if (cam->sensor == client) {
513 cafe_ctlr_stop_dma(cam);
514 cafe_ctlr_power_down(cam);
515 cam_err(cam, "lost the sensor!\n");
516 cam->sensor = NULL; /* Bummer, no camera */
517 cam->state = S_NOTREADY;
518 }
519 return 0;
520}
521
522static int cafe_smbus_setup(struct cafe_camera *cam) 486static int cafe_smbus_setup(struct cafe_camera *cam)
523{ 487{
524 struct i2c_adapter *adap = &cam->i2c_adapter; 488 struct i2c_adapter *adap = &cam->i2c_adapter;
@@ -527,8 +491,6 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
527 cafe_smbus_enable_irq(cam); 491 cafe_smbus_enable_irq(cam);
528 adap->id = I2C_HW_SMBUS_CAFE; 492 adap->id = I2C_HW_SMBUS_CAFE;
529 adap->owner = THIS_MODULE; 493 adap->owner = THIS_MODULE;
530 adap->client_register = cafe_smbus_attach;
531 adap->client_unregister = cafe_smbus_detach;
532 adap->algo = &cafe_smbus_algo; 494 adap->algo = &cafe_smbus_algo;
533 strcpy(adap->name, "cafe_ccic"); 495 strcpy(adap->name, "cafe_ccic");
534 adap->dev.parent = &cam->pdev->dev; 496 adap->dev.parent = &cam->pdev->dev;
@@ -790,23 +752,9 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam)
790 * Communications with the sensor. 752 * Communications with the sensor.
791 */ 753 */
792 754
793static int __cafe_cam_cmd(struct cafe_camera *cam, int cmd, void *arg)
794{
795 struct i2c_client *sc = cam->sensor;
796 int ret;
797
798 if (sc == NULL || sc->driver == NULL || sc->driver->command == NULL)
799 return -EINVAL;
800 ret = sc->driver->command(sc, cmd, arg);
801 if (ret == -EPERM) /* Unsupported command */
802 return 0;
803 return ret;
804}
805
806static int __cafe_cam_reset(struct cafe_camera *cam) 755static int __cafe_cam_reset(struct cafe_camera *cam)
807{ 756{
808 int zero = 0; 757 return sensor_call(cam, core, reset, 0);
809 return __cafe_cam_cmd(cam, VIDIOC_INT_RESET, &zero);
810} 758}
811 759
812/* 760/*
@@ -826,14 +774,13 @@ static int cafe_cam_init(struct cafe_camera *cam)
826 if (ret) 774 if (ret)
827 goto out; 775 goto out;
828 chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR; 776 chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
829 chip.match.addr = cam->sensor->addr; 777 chip.match.addr = cam->sensor_addr;
830 ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip); 778 ret = sensor_call(cam, core, g_chip_ident, &chip);
831 if (ret) 779 if (ret)
832 goto out; 780 goto out;
833 cam->sensor_type = chip.ident; 781 cam->sensor_type = chip.ident;
834/* if (cam->sensor->addr != OV7xx0_SID) { */
835 if (cam->sensor_type != V4L2_IDENT_OV7670) { 782 if (cam->sensor_type != V4L2_IDENT_OV7670) {
836 cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr); 783 cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
837 ret = -EINVAL; 784 ret = -EINVAL;
838 goto out; 785 goto out;
839 } 786 }
@@ -857,21 +804,21 @@ static int cafe_cam_set_flip(struct cafe_camera *cam)
857 memset(&ctrl, 0, sizeof(ctrl)); 804 memset(&ctrl, 0, sizeof(ctrl));
858 ctrl.id = V4L2_CID_VFLIP; 805 ctrl.id = V4L2_CID_VFLIP;
859 ctrl.value = flip; 806 ctrl.value = flip;
860 return __cafe_cam_cmd(cam, VIDIOC_S_CTRL, &ctrl); 807 return sensor_call(cam, core, s_ctrl, &ctrl);
861} 808}
862 809
863 810
864static int cafe_cam_configure(struct cafe_camera *cam) 811static int cafe_cam_configure(struct cafe_camera *cam)
865{ 812{
866 struct v4l2_format fmt; 813 struct v4l2_format fmt;
867 int ret, zero = 0; 814 int ret;
868 815
869 if (cam->state != S_IDLE) 816 if (cam->state != S_IDLE)
870 return -EINVAL; 817 return -EINVAL;
871 fmt.fmt.pix = cam->pix_format; 818 fmt.fmt.pix = cam->pix_format;
872 ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero); 819 ret = sensor_call(cam, core, init, 0);
873 if (ret == 0) 820 if (ret == 0)
874 ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt); 821 ret = sensor_call(cam, video, s_fmt, &fmt);
875 /* 822 /*
876 * OV7670 does weird things if flip is set *before* format... 823 * OV7670 does weird things if flip is set *before* format...
877 */ 824 */
@@ -1490,7 +1437,7 @@ static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
1490 int ret; 1437 int ret;
1491 1438
1492 mutex_lock(&cam->s_mutex); 1439 mutex_lock(&cam->s_mutex);
1493 ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc); 1440 ret = sensor_call(cam, core, queryctrl, qc);
1494 mutex_unlock(&cam->s_mutex); 1441 mutex_unlock(&cam->s_mutex);
1495 return ret; 1442 return ret;
1496} 1443}
@@ -1503,7 +1450,7 @@ static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
1503 int ret; 1450 int ret;
1504 1451
1505 mutex_lock(&cam->s_mutex); 1452 mutex_lock(&cam->s_mutex);
1506 ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl); 1453 ret = sensor_call(cam, core, g_ctrl, ctrl);
1507 mutex_unlock(&cam->s_mutex); 1454 mutex_unlock(&cam->s_mutex);
1508 return ret; 1455 return ret;
1509} 1456}
@@ -1516,7 +1463,7 @@ static int cafe_vidioc_s_ctrl(struct file *filp, void *priv,
1516 int ret; 1463 int ret;
1517 1464
1518 mutex_lock(&cam->s_mutex); 1465 mutex_lock(&cam->s_mutex);
1519 ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl); 1466 ret = sensor_call(cam, core, s_ctrl, ctrl);
1520 mutex_unlock(&cam->s_mutex); 1467 mutex_unlock(&cam->s_mutex);
1521 return ret; 1468 return ret;
1522} 1469}
@@ -1558,7 +1505,7 @@ static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
1558 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1505 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1559 return -EINVAL; 1506 return -EINVAL;
1560 mutex_lock(&cam->s_mutex); 1507 mutex_lock(&cam->s_mutex);
1561 ret = __cafe_cam_cmd(cam, VIDIOC_ENUM_FMT, fmt); 1508 ret = sensor_call(cam, video, enum_fmt, fmt);
1562 mutex_unlock(&cam->s_mutex); 1509 mutex_unlock(&cam->s_mutex);
1563 return ret; 1510 return ret;
1564} 1511}
@@ -1571,7 +1518,7 @@ static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
1571 int ret; 1518 int ret;
1572 1519
1573 mutex_lock(&cam->s_mutex); 1520 mutex_lock(&cam->s_mutex);
1574 ret = __cafe_cam_cmd(cam, VIDIOC_TRY_FMT, fmt); 1521 ret = sensor_call(cam, video, try_fmt, fmt);
1575 mutex_unlock(&cam->s_mutex); 1522 mutex_unlock(&cam->s_mutex);
1576 return ret; 1523 return ret;
1577} 1524}
@@ -1680,7 +1627,7 @@ static int cafe_vidioc_g_parm(struct file *filp, void *priv,
1680 int ret; 1627 int ret;
1681 1628
1682 mutex_lock(&cam->s_mutex); 1629 mutex_lock(&cam->s_mutex);
1683 ret = __cafe_cam_cmd(cam, VIDIOC_G_PARM, parms); 1630 ret = sensor_call(cam, video, g_parm, parms);
1684 mutex_unlock(&cam->s_mutex); 1631 mutex_unlock(&cam->s_mutex);
1685 parms->parm.capture.readbuffers = n_dma_bufs; 1632 parms->parm.capture.readbuffers = n_dma_bufs;
1686 return ret; 1633 return ret;
@@ -1693,7 +1640,7 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv,
1693 int ret; 1640 int ret;
1694 1641
1695 mutex_lock(&cam->s_mutex); 1642 mutex_lock(&cam->s_mutex);
1696 ret = __cafe_cam_cmd(cam, VIDIOC_S_PARM, parms); 1643 ret = sensor_call(cam, video, s_parm, parms);
1697 mutex_unlock(&cam->s_mutex); 1644 mutex_unlock(&cam->s_mutex);
1698 parms->parm.capture.readbuffers = n_dma_bufs; 1645 parms->parm.capture.readbuffers = n_dma_bufs;
1699 return ret; 1646 return ret;
@@ -1973,7 +1920,7 @@ static ssize_t cafe_dfs_read_cam(struct file *file,
1973 { 1920 {
1974 u8 v; 1921 u8 v;
1975 1922
1976 cafe_smbus_read_data(cam, cam->sensor->addr, offset, &v); 1923 cafe_smbus_read_data(cam, cam->sensor_addr, offset, &v);
1977 s += sprintf(s, "%02x: %02x\n", offset, v); 1924 s += sprintf(s, "%02x: %02x\n", offset, v);
1978 } 1925 }
1979 return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf, 1926 return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
@@ -2089,6 +2036,18 @@ static int cafe_pci_probe(struct pci_dev *pdev,
2089 ret = cafe_smbus_setup(cam); 2036 ret = cafe_smbus_setup(cam);
2090 if (ret) 2037 if (ret)
2091 goto out_freeirq; 2038 goto out_freeirq;
2039
2040 cam->sensor_addr = 0x42;
2041 cam->sensor = v4l2_i2c_new_subdev(&cam->i2c_adapter,
2042 "ov7670", "ov7670", cam->sensor_addr);
2043 if (cam->sensor == NULL) {
2044 ret = -ENODEV;
2045 goto out_smbus;
2046 }
2047 ret = cafe_cam_init(cam);
2048 if (ret)
2049 goto out_smbus;
2050
2092 /* 2051 /*
2093 * Get the v4l2 setup done. 2052 * Get the v4l2 setup done.
2094 */ 2053 */
@@ -2263,7 +2222,6 @@ static int __init cafe_init(void)
2263 printk(KERN_ERR "Unable to register cafe_ccic driver\n"); 2222 printk(KERN_ERR "Unable to register cafe_ccic driver\n");
2264 goto out; 2223 goto out;
2265 } 2224 }
2266 request_module("ov7670"); /* FIXME want something more general */
2267 ret = 0; 2225 ret = 0;
2268 2226
2269 out: 2227 out: