aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa5246a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/saa5246a.c')
-rw-r--r--drivers/media/video/saa5246a.c69
1 files changed, 45 insertions, 24 deletions
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index 8f117bd50b86..da47b2f05288 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,10 +46,11 @@
46#include <linux/smp_lock.h> 46#include <linux/smp_lock.h>
47#include <linux/mutex.h> 47#include <linux/mutex.h>
48#include <linux/videotext.h> 48#include <linux/videotext.h>
49#include <linux/videodev.h> 49#include <linux/videodev2.h>
50#include <media/v4l2-common.h> 50#include <media/v4l2-device.h>
51#include <media/v4l2-chip-ident.h>
51#include <media/v4l2-ioctl.h> 52#include <media/v4l2-ioctl.h>
52#include <media/v4l2-i2c-drv-legacy.h> 53#include <media/v4l2-i2c-drv.h>
53 54
54MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>"); 55MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
55MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver"); 56MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
@@ -388,13 +389,19 @@ MODULE_LICENSE("GPL");
388 389
389struct saa5246a_device 390struct saa5246a_device
390{ 391{
392 struct v4l2_subdev sd;
393 struct video_device *vdev;
391 u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE]; 394 u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
392 int is_searching[NUM_DAUS]; 395 int is_searching[NUM_DAUS];
393 struct i2c_client *client;
394 unsigned long in_use; 396 unsigned long in_use;
395 struct mutex lock; 397 struct mutex lock;
396}; 398};
397 399
400static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd)
401{
402 return container_of(sd, struct saa5246a_device, sd);
403}
404
398static struct video_device saa_template; /* Declared near bottom */ 405static struct video_device saa_template; /* Declared near bottom */
399 406
400/* 407/*
@@ -403,12 +410,13 @@ static struct video_device saa_template; /* Declared near bottom */
403 410
404static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data) 411static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
405{ 412{
413 struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
406 char buf[64]; 414 char buf[64];
407 415
408 buf[0] = reg; 416 buf[0] = reg;
409 memcpy(buf+1, data, count); 417 memcpy(buf+1, data, count);
410 418
411 if(i2c_master_send(t->client, buf, count+1)==count+1) 419 if (i2c_master_send(client, buf, count + 1) == count + 1)
412 return 0; 420 return 0;
413 return -1; 421 return -1;
414} 422}
@@ -436,7 +444,9 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
436 */ 444 */
437static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf) 445static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
438{ 446{
439 if(i2c_master_recv(t->client, buf, count)!=count) 447 struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
448
449 if (i2c_master_recv(client, buf, count) != count)
440 return -1; 450 return -1;
441 return 0; 451 return 0;
442} 452}
@@ -961,9 +971,6 @@ static int saa5246a_open(struct file *file)
961{ 971{
962 struct saa5246a_device *t = video_drvdata(file); 972 struct saa5246a_device *t = video_drvdata(file);
963 973
964 if (t->client == NULL)
965 return -ENODEV;
966
967 if (test_and_set_bit(0, &t->in_use)) 974 if (test_and_set_bit(0, &t->in_use))
968 return -EBUSY; 975 return -EBUSY;
969 976
@@ -1033,18 +1040,29 @@ static struct video_device saa_template =
1033 .minor = -1, 1040 .minor = -1,
1034}; 1041};
1035 1042
1036/* Addresses to scan */ 1043static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
1037static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; 1044{
1045 struct i2c_client *client = v4l2_get_subdevdata(sd);
1046
1047 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0);
1048}
1049
1050static const struct v4l2_subdev_core_ops saa5246a_core_ops = {
1051 .g_chip_ident = saa5246a_g_chip_ident,
1052};
1053
1054static const struct v4l2_subdev_ops saa5246a_ops = {
1055 .core = &saa5246a_core_ops,
1056};
1038 1057
1039I2C_CLIENT_INSMOD;
1040 1058
1041static int saa5246a_probe(struct i2c_client *client, 1059static int saa5246a_probe(struct i2c_client *client,
1042 const struct i2c_device_id *id) 1060 const struct i2c_device_id *id)
1043{ 1061{
1044 int pgbuf; 1062 int pgbuf;
1045 int err; 1063 int err;
1046 struct video_device *vd;
1047 struct saa5246a_device *t; 1064 struct saa5246a_device *t;
1065 struct v4l2_subdev *sd;
1048 1066
1049 v4l_info(client, "chip found @ 0x%x (%s)\n", 1067 v4l_info(client, "chip found @ 0x%x (%s)\n",
1050 client->addr << 1, client->adapter->name); 1068 client->addr << 1, client->adapter->name);
@@ -1053,40 +1071,43 @@ static int saa5246a_probe(struct i2c_client *client,
1053 t = kzalloc(sizeof(*t), GFP_KERNEL); 1071 t = kzalloc(sizeof(*t), GFP_KERNEL);
1054 if (t == NULL) 1072 if (t == NULL)
1055 return -ENOMEM; 1073 return -ENOMEM;
1074 sd = &t->sd;
1075 v4l2_i2c_subdev_init(sd, client, &saa5246a_ops);
1056 mutex_init(&t->lock); 1076 mutex_init(&t->lock);
1057 1077
1058 /* Now create a video4linux device */ 1078 /* Now create a video4linux device */
1059 vd = video_device_alloc(); 1079 t->vdev = video_device_alloc();
1060 if (vd == NULL) { 1080 if (t->vdev == NULL) {
1061 kfree(t); 1081 kfree(t);
1062 return -ENOMEM; 1082 return -ENOMEM;
1063 } 1083 }
1064 i2c_set_clientdata(client, vd); 1084 memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
1065 memcpy(vd, &saa_template, sizeof(*vd));
1066 1085
1067 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) { 1086 for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
1068 memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0])); 1087 memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
1069 t->is_searching[pgbuf] = false; 1088 t->is_searching[pgbuf] = false;
1070 } 1089 }
1071 video_set_drvdata(vd, t); 1090 video_set_drvdata(t->vdev, t);
1072 1091
1073 /* Register it */ 1092 /* Register it */
1074 err = video_register_device(vd, VFL_TYPE_VTX, -1); 1093 err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
1075 if (err < 0) { 1094 if (err < 0) {
1076 kfree(t); 1095 kfree(t);
1077 video_device_release(vd); 1096 video_device_release(t->vdev);
1097 t->vdev = NULL;
1078 return err; 1098 return err;
1079 } 1099 }
1080 t->client = client;
1081 return 0; 1100 return 0;
1082} 1101}
1083 1102
1084static int saa5246a_remove(struct i2c_client *client) 1103static int saa5246a_remove(struct i2c_client *client)
1085{ 1104{
1086 struct video_device *vd = i2c_get_clientdata(client); 1105 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1106 struct saa5246a_device *t = to_dev(sd);
1087 1107
1088 video_unregister_device(vd); 1108 video_unregister_device(t->vdev);
1089 kfree(video_get_drvdata(vd)); 1109 v4l2_device_unregister_subdev(sd);
1110 kfree(t);
1090 return 0; 1111 return 0;
1091} 1112}
1092 1113