aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa5249.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa5249.c')
-rw-r--r--drivers/media/video/saa5249.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index e29765192469..48b27fe48087 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -50,15 +50,17 @@
50#include <linux/mutex.h> 50#include <linux/mutex.h>
51#include <linux/delay.h> 51#include <linux/delay.h>
52#include <linux/videotext.h> 52#include <linux/videotext.h>
53#include <linux/videodev.h> 53#include <linux/videodev2.h>
54#include <media/v4l2-common.h> 54#include <media/v4l2-device.h>
55#include <media/v4l2-chip-ident.h>
55#include <media/v4l2-ioctl.h> 56#include <media/v4l2-ioctl.h>
56#include <media/v4l2-i2c-drv-legacy.h> 57#include <media/v4l2-i2c-drv.h>
57 58
58MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); 59MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
59MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver"); 60MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver");
60MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
61 62
63
62#define VTX_VER_MAJ 1 64#define VTX_VER_MAJ 1
63#define VTX_VER_MIN 8 65#define VTX_VER_MIN 8
64 66
@@ -95,17 +97,23 @@ typedef struct {
95 97
96struct saa5249_device 98struct saa5249_device
97{ 99{
100 struct v4l2_subdev sd;
101 struct video_device *vdev;
98 vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */ 102 vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
99 /* real DAU, so we have to simulate some more) */ 103 /* real DAU, so we have to simulate some more) */
100 int vtx_use_count; 104 int vtx_use_count;
101 int is_searching[NUM_DAUS]; 105 int is_searching[NUM_DAUS];
102 int disp_mode; 106 int disp_mode;
103 int virtual_mode; 107 int virtual_mode;
104 struct i2c_client *client;
105 unsigned long in_use; 108 unsigned long in_use;
106 struct mutex lock; 109 struct mutex lock;
107}; 110};
108 111
112static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd)
113{
114 return container_of(sd, struct saa5249_device, sd);
115}
116
109 117
110#define CCTWR 34 /* I²C write/read-address of vtx-chip */ 118#define CCTWR 34 /* I²C write/read-address of vtx-chip */
111#define CCTRD 35 119#define CCTRD 35
@@ -147,12 +155,13 @@ static void jdelay(unsigned long delay)
147 155
148static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data) 156static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
149{ 157{
158 struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
150 char buf[64]; 159 char buf[64];
151 160
152 buf[0] = reg; 161 buf[0] = reg;
153 memcpy(buf+1, data, count); 162 memcpy(buf+1, data, count);
154 163
155 if (i2c_master_send(t->client, buf, count + 1) == count + 1) 164 if (i2c_master_send(client, buf, count + 1) == count + 1)
156 return 0; 165 return 0;
157 return -1; 166 return -1;
158} 167}
@@ -180,7 +189,9 @@ static int i2c_senddata(struct saa5249_device *t, ...)
180 189
181static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf) 190static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
182{ 191{
183 if(i2c_master_recv(t->client, buf, count)!=count) 192 struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
193
194 if (i2c_master_recv(client, buf, count) != count)
184 return -1; 195 return -1;
185 return 0; 196 return 0;
186} 197}
@@ -497,9 +508,6 @@ static int saa5249_open(struct file *file)
497 struct saa5249_device *t = video_drvdata(file); 508 struct saa5249_device *t = video_drvdata(file);
498 int pgbuf; 509 int pgbuf;
499 510
500 if (t->client == NULL)
501 return -ENODEV;
502
503 if (test_and_set_bit(0, &t->in_use)) 511 if (test_and_set_bit(0, &t->in_use))
504 return -EBUSY; 512 return -EBUSY;
505 513
@@ -553,18 +561,28 @@ static struct video_device saa_template =
553 .release = video_device_release, 561 .release = video_device_release,
554}; 562};
555 563
556/* Addresses to scan */ 564static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
557static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; 565{
566 struct i2c_client *client = v4l2_get_subdevdata(sd);
567
568 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0);
569}
558 570
559I2C_CLIENT_INSMOD; 571static const struct v4l2_subdev_core_ops saa5249_core_ops = {
572 .g_chip_ident = saa5249_g_chip_ident,
573};
574
575static const struct v4l2_subdev_ops saa5249_ops = {
576 .core = &saa5249_core_ops,
577};
560 578
561static int saa5249_probe(struct i2c_client *client, 579static int saa5249_probe(struct i2c_client *client,
562 const struct i2c_device_id *id) 580 const struct i2c_device_id *id)
563{ 581{
564 int pgbuf; 582 int pgbuf;
565 int err; 583 int err;
566 struct video_device *vd;
567 struct saa5249_device *t; 584 struct saa5249_device *t;
585 struct v4l2_subdev *sd;
568 586
569 v4l_info(client, "chip found @ 0x%x (%s)\n", 587 v4l_info(client, "chip found @ 0x%x (%s)\n",
570 client->addr << 1, client->adapter->name); 588 client->addr << 1, client->adapter->name);
@@ -573,16 +591,17 @@ static int saa5249_probe(struct i2c_client *client,
573 t = kzalloc(sizeof(*t), GFP_KERNEL); 591 t = kzalloc(sizeof(*t), GFP_KERNEL);
574 if (t == NULL) 592 if (t == NULL)
575 return -ENOMEM; 593 return -ENOMEM;
594 sd = &t->sd;
595 v4l2_i2c_subdev_init(sd, client, &saa5249_ops);
576 mutex_init(&t->lock); 596 mutex_init(&t->lock);
577 597
578 /* Now create a video4linux device */ 598 /* Now create a video4linux device */
579 vd = kmalloc(sizeof(struct video_device), GFP_KERNEL); 599 t->vdev = video_device_alloc();
580 if (vd == NULL) { 600 if (t->vdev == NULL) {
581 kfree(client); 601 kfree(client);
582 return -ENOMEM; 602 return -ENOMEM;
583 } 603 }
584 i2c_set_clientdata(client, vd); 604 memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
585 memcpy(vd, &saa_template, sizeof(*vd));
586 605
587 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { 606 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
588 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf)); 607 memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
@@ -593,26 +612,27 @@ static int saa5249_probe(struct i2c_client *client,
593 t->vdau[pgbuf].stopped = true; 612 t->vdau[pgbuf].stopped = true;
594 t->is_searching[pgbuf] = false; 613 t->is_searching[pgbuf] = false;
595 } 614 }
596 video_set_drvdata(vd, t); 615 video_set_drvdata(t->vdev, t);
597 616
598 /* Register it */ 617 /* Register it */
599 err = video_register_device(vd, VFL_TYPE_VTX, -1); 618 err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
600 if (err < 0) { 619 if (err < 0) {
601 kfree(t); 620 kfree(t);
602 kfree(vd); 621 video_device_release(t->vdev);
622 t->vdev = NULL;
603 return err; 623 return err;
604 } 624 }
605 t->client = client;
606 return 0; 625 return 0;
607} 626}
608 627
609static int saa5249_remove(struct i2c_client *client) 628static int saa5249_remove(struct i2c_client *client)
610{ 629{
611 struct video_device *vd = i2c_get_clientdata(client); 630 struct v4l2_subdev *sd = i2c_get_clientdata(client);
631 struct saa5249_device *t = to_dev(sd);
612 632
613 video_unregister_device(vd); 633 video_unregister_device(t->vdev);
614 kfree(video_get_drvdata(vd)); 634 v4l2_device_unregister_subdev(sd);
615 kfree(vd); 635 kfree(t);
616 return 0; 636 return 0;
617} 637}
618 638
@@ -624,7 +644,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id);
624 644
625static struct v4l2_i2c_driver_data v4l2_i2c_data = { 645static struct v4l2_i2c_driver_data v4l2_i2c_data = {
626 .name = "saa5249", 646 .name = "saa5249",
627 .driverid = I2C_DRIVERID_SAA5249,
628 .probe = saa5249_probe, 647 .probe = saa5249_probe,
629 .remove = saa5249_remove, 648 .remove = saa5249_remove,
630 .id_table = saa5249_id, 649 .id_table = saa5249_id,