Re: go7007 question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 06, 2012 at 11:10:14PM +0400, Volokh Konstantin wrote:
> On Mon, Sep 03, 2012 at 02:37:16PM -0400, Adam Rosi-Kessel wrote:
> > 
> > [469.928881] wis-saa7115: initializing SAA7115 at address 32 on WIS
> > GO7007SB EZ-USB
> > 
> > [469.989083] go7007: probing for module i2c:wis_saa7115 failed
> > 
> > [470.004785] wis-uda1342: initializing UDA1342 at address 26 on WIS
> > GO7007SB EZ-USB
> > 
> > [470.005454] go7007: probing for module i2c:wis_uda1342 failed
> > 
> > [470.011659] wis-sony-tuner: initializing tuner at address 96 on WIS
> > GO7007SB EZ-USB
Hi, I generated patchs, that u may in your own go7007/ folder
It contains go7007 initialization and i2c_subdev fixing

It was checked for 3.6 branch (compile only)
 
Regards,
Volokh Konstantin
diff --git a/drivers/staging/media/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index ece2dd1..2dff9b5 100644
--- a/drivers/staging/media/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
@@ -173,6 +173,11 @@ static int go7007_init_encoder(struct go7007 *go)
 		go7007_write_addr(go, 0x3c82, 0x0001);
 		go7007_write_addr(go, 0x3c80, 0x00fe);
 	}
+	if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
+		/* set GPIO5 to be an output, currently low */
+		go7007_write_addr(go, 0x3c82, 0x0000);
+		go7007_write_addr(go, 0x3c80, 0x00df);
+	}
 	return 0;
 }
 
@@ -192,17 +197,23 @@ int go7007_reset_encoder(struct go7007 *go)
 /*
  * Attempt to instantiate an I2C client by ID, probably loading a module.
  */
-static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
-			   int addr)
+static int init_i2c_module(struct i2c_adapter *adapter, const struct go_i2c *const i2c)
 {
 	struct go7007 *go = i2c_get_adapdata(adapter);
 	struct v4l2_device *v4l2_dev = &go->v4l2_dev;
+	struct i2c_board_info info;
+
+	memset(&info, 0, sizeof(info));
+	strlcpy(info.type, i2c->type, sizeof(info.type));
+	info.addr = i2c->addr;
 
-	if (v4l2_i2c_new_subdev(v4l2_dev, adapter, type, addr, NULL))
+	if (i2c->id == I2C_DRIVERID_WIS_TW2804)
+		info.flags |= I2C_CLIENT_TEN;
+	if (v4l2_i2c_new_subdev_board(v4l2_dev, adapter, &info, NULL))
 		return 0;
 
-	printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", type);
-	return -1;
+	printk(KERN_INFO "go7007: probing for module i2c:%s failed\n", i2c->type);
+	return -EINVAL;
 }
 
 /*
@@ -238,9 +249,7 @@ int go7007_register_encoder(struct go7007 *go)
 	}
 	if (go->i2c_adapter_online) {
 		for (i = 0; i < go->board_info->num_i2c_devs; ++i)
-			init_i2c_module(&go->i2c_adapter,
-					go->board_info->i2c_devs[i].type,
-					go->board_info->i2c_devs[i].addr);
+			init_i2c_module(&go->i2c_adapter, &go->board_info->i2c_devs[i]);
 		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
 			i2c_clients_command(&go->i2c_adapter,
 				DECODER_SET_CHANNEL, &go->channel_number);
@@ -571,7 +580,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
 	struct go7007 *go;
 	int i;
 
-	go = kmalloc(sizeof(struct go7007), GFP_KERNEL);
+	go = kzalloc(sizeof(struct go7007), GFP_KERNEL);
 	if (go == NULL)
 		return NULL;
 	go->dev = dev;
diff --git a/drivers/staging/media/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b58c394..b7b939a 100644
--- a/drivers/staging/media/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
@@ -88,7 +88,7 @@ struct go7007_board_info {
 	int audio_bclk_div;
 	int audio_main_div;
 	int num_i2c_devs;
-	struct {
+	struct go_i2c {
 		const char *type;
 		int id;
 		int addr;
diff --git a/drivers/staging/media/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 5443e25..9dbf5ec 100644
--- a/drivers/staging/media/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
@@ -1110,9 +1110,6 @@ static int go7007_usb_probe(struct usb_interface *intf,
 			} else {
 				u16 channel;
 
-				/* set GPIO5 to be an output, currently low */
-				go7007_write_addr(go, 0x3c82, 0x0000);
-				go7007_write_addr(go, 0x3c80, 0x00df);
 				/* read channel number from GPIO[1:0] */
 				go7007_read_addr(go, 0x3c81, &channel);
 				channel &= 0x3;
@@ -1245,7 +1242,6 @@ static void go7007_usb_disconnect(struct usb_interface *intf)
 	struct urb *vurb, *aurb;
 	int i;
 
-	go->status = STATUS_SHUTDOWN;
 	usb_kill_urb(usb->intr_urb);
 
 	/* Free USB-related structs */
@@ -1269,6 +1265,7 @@ static void go7007_usb_disconnect(struct usb_interface *intf)
 	kfree(go->hpi_context);
 
 	go7007_remove(go);
+	go->status = STATUS_SHUTDOWN;
 }
 
 static struct usb_driver go7007_usb_driver = {
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index c184ad3..b8f2eb6 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -98,7 +98,7 @@ static int go7007_open(struct file *file)
 
 	if (go->status != STATUS_ONLINE)
 		return -EBUSY;
-	gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
+	gofh = kzalloc(sizeof(struct go7007_file), GFP_KERNEL);
 	if (gofh == NULL)
 		return -ENOMEM;
 	++go->ref_count;
@@ -953,6 +953,7 @@ static int vidioc_streamon(struct file *file, void *priv,
 	}
 	mutex_unlock(&go->hw_lock);
 	mutex_unlock(&gofh->lock);
+	call_all(&go->v4l2_dev, video, s_stream, 1);
 
 	return retval;
 }
@@ -968,6 +969,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
 	mutex_lock(&gofh->lock);
 	go7007_streamoff(go);
 	mutex_unlock(&gofh->lock);
+	call_all(&go->v4l2_dev, video, s_stream, 0);
 
 	return 0;
 }
@@ -1832,5 +1834,6 @@ void go7007_v4l2_remove(struct go7007 *go)
 	mutex_unlock(&go->hw_lock);
 	if (go->video_dev)
 		video_unregister_device(go->video_dev);
-	v4l2_device_unregister(&go->v4l2_dev);
+	if (go->status != STATUS_SHUTDOWN)
+		v4l2_device_unregister(&go->v4l2_dev);
 }
diff --git a/drivers/staging/media/go7007/wis-saa7115.c b/drivers/staging/media/go7007/wis-saa7115.c
index 46cff59..9065cc7 100644
--- a/drivers/staging/media/go7007/wis-saa7115.c
+++ b/drivers/staging/media/go7007/wis-saa7115.c
@@ -21,10 +21,17 @@
 #include <linux/videodev2.h>
 #include <linux/ioctl.h>
 #include <linux/slab.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
 
 #include "wis-i2c.h"
 
 struct wis_saa7115 {
+  struct v4l2_subdev sd;
+  struct v4l2_ctrl_handler hdl;
 	int norm;
 	int brightness;
 	int contrast;
@@ -182,6 +189,15 @@ static u8 initial_registers[] =
 	0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
 };
 
+static const struct v4l2_subdev_core_ops wis_saa7115_core_ops = {
+};
+
+static const struct v4l2_subdev_video_ops wis_saa7115_video_ops = {
+/*  .s_routing = tw2804_s_video_routing,
+  .s_mbus_fmt = tw2804_s_mbus_fmt,
+  .s_stream = tw2804_s_stream,*/
+};
+
 static int write_reg(struct i2c_client *client, u8 reg, u8 value)
 {
 	return i2c_smbus_write_byte_data(client, reg, value);
@@ -197,10 +213,16 @@ static int write_regs(struct i2c_client *client, u8 *regs)
 	return 0;
 }
 
+inline struct wis_saa7115 *to_state(struct v4l2_subdev *sd)
+{
+  return container_of(sd, struct wis_saa7115, sd);
+}
+
 static int wis_saa7115_command(struct i2c_client *client,
 				unsigned int cmd, void *arg)
 {
-	struct wis_saa7115 *dec = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+  struct wis_saa7115 *dec = to_state(sd);
 
 	switch (cmd) {
 	case VIDIOC_S_INPUT:
@@ -395,11 +417,18 @@ static int wis_saa7115_command(struct i2c_client *client,
 	return 0;
 }
 
+static const struct v4l2_subdev_ops wis_saa7115_ops = {
+  .core = &wis_saa7115_core_ops,
+  .video = &wis_saa7115_video_ops,
+//  .video = &wis_sony_tuner_video_ops,
+};
+
 static int wis_saa7115_probe(struct i2c_client *client,
 			     const struct i2c_device_id *id)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct wis_saa7115 *dec;
+  struct v4l2_subdev *sd;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
@@ -407,13 +436,14 @@ static int wis_saa7115_probe(struct i2c_client *client,
 	dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
 	if (dec == NULL)
 		return -ENOMEM;
+  sd = &dec->sd;
+  v4l2_i2c_subdev_init(sd, client, &wis_saa7115_ops);
 
 	dec->norm = V4L2_STD_NTSC;
 	dec->brightness = 128;
 	dec->contrast = 64;
 	dec->saturation = 64;
 	dec->hue = 0;
-	i2c_set_clientdata(client, dec);
 
 	printk(KERN_DEBUG
 		"wis-saa7115: initializing SAA7115 at address %d on %s\n",
@@ -431,8 +461,10 @@ static int wis_saa7115_probe(struct i2c_client *client,
 
 static int wis_saa7115_remove(struct i2c_client *client)
 {
-	struct wis_saa7115 *dec = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct wis_saa7115 *dec = to_state(sd);
 
+  v4l2_device_unregister_subdev(sd);
 	kfree(dec);
 	return 0;
 }
diff --git a/drivers/staging/media/go7007/wis-sony-tuner.c b/drivers/staging/media/go7007/wis-sony-tuner.c
index 8f1b7d4..884a261 100644
--- a/drivers/staging/media/go7007/wis-sony-tuner.c
+++ b/drivers/staging/media/go7007/wis-sony-tuner.c
@@ -23,6 +23,9 @@
 #include <media/tuner.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
 
 #include "wis-i2c.h"
 
@@ -67,6 +70,8 @@ static struct sony_tunertype sony_tuners[] = {
 };
 
 struct wis_sony_tuner {
+  struct v4l2_subdev sd;
+  struct v4l2_ctrl_handler hdl;
 	int type;
 	v4l2_std_id std;
 	unsigned int freq;
@@ -74,10 +79,32 @@ struct wis_sony_tuner {
 	u32 audmode;
 };
 
+inline struct wis_sony_tuner *to_state(struct v4l2_subdev *sd)
+{
+  return container_of(sd, struct wis_sony_tuner, sd);
+}
+
+static const struct v4l2_subdev_tuner_ops wis_sony_tuner_ops = {
+};
+
+static const struct v4l2_subdev_core_ops wis_sony_core_ops = {
+/*  .log_status = wis_sony_tuner_log_status,
+  .g_chip_ident = wis_sony_tuner_g_chip_ident,
+  .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
+  .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
+  .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
+  .g_ctrl = v4l2_subdev_g_ctrl,
+  .s_ctrl = v4l2_subdev_s_ctrl,
+  .queryctrl = v4l2_subdev_queryctrl,
+  .querymenu = v4l2_subdev_querymenu,
+  .s_std = wis_sony_tuner_s_std,*/
+};
+
 /* Basically the same as default_set_tv_freq() in tuner.c */
 static int set_freq(struct i2c_client *client, int freq)
 {
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct wis_sony_tuner *t = to_state(sd);
 	char *band_name;
 	int n;
 	int band_select;
@@ -220,7 +247,8 @@ static struct {
 
 static int mpx_setup(struct i2c_client *client)
 {
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+  struct wis_sony_tuner *t = to_state(sd);
 	u16 source = 0;
 	u8 buffer[3];
 	struct i2c_msg msg;
@@ -336,7 +364,8 @@ static int mpx_setup(struct i2c_client *client)
 
 static int set_if(struct i2c_client *client)
 {
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+  struct wis_sony_tuner *t = to_state(sd);
 	u8 buffer[4];
 	struct i2c_msg msg;
 	int default_mpx_mode = 0;
@@ -384,7 +413,8 @@ static int set_if(struct i2c_client *client)
 
 static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 {
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+  struct wis_sony_tuner *t = to_state(sd);
 
 	switch (cmd) {
 #if 0
@@ -654,24 +684,33 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
 	return 0;
 }
 
+
+static const struct v4l2_subdev_ops wis_sony_ops = {
+  .core = &wis_sony_core_ops,
+  .tuner = &wis_sony_tuner_ops,
+//  .video = &wis_sony_tuner_video_ops,
+};
+
 static int wis_sony_tuner_probe(struct i2c_client *client,
 				const struct i2c_device_id *id)
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct wis_sony_tuner *t;
+  struct v4l2_subdev *sd;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -ENODEV;
 
-	t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
+	t = kzalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
 	if (t == NULL)
 		return -ENOMEM;
+  sd = &t->sd;
+  v4l2_i2c_subdev_init(sd, client, &wis_sony_ops);
 
 	t->type = -1;
 	t->freq = 0;
 	t->mpxmode = 0;
 	t->audmode = V4L2_TUNER_MODE_STEREO;
-	i2c_set_clientdata(client, t);
 
 	printk(KERN_DEBUG
 		"wis-sony-tuner: initializing tuner at address %d on %s\n",
@@ -682,8 +721,10 @@ static int wis_sony_tuner_probe(struct i2c_client *client,
 
 static int wis_sony_tuner_remove(struct i2c_client *client)
 {
-	struct wis_sony_tuner *t = i2c_get_clientdata(client);
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+  struct wis_sony_tuner *t = to_state(sd);
 
+  v4l2_device_unregister_subdev(sd);
 	kfree(t);
 	return 0;
 }
diff --git a/drivers/staging/media/go7007/wis-uda1342.c b/drivers/staging/media/go7007/wis-uda1342.c
index 0127be2..83aa1b9 100644
--- a/drivers/staging/media/go7007/wis-uda1342.c
+++ b/drivers/staging/media/go7007/wis-uda1342.c
@@ -18,9 +18,14 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/videodev2.h>
 #include <media/tvaudio.h>
 #include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
 
 #include "wis-i2c.h"
 
@@ -31,6 +36,9 @@ static int write_reg(struct i2c_client *client, int reg, int value)
 	return 0;
 }
 
+static const struct v4l2_subdev_audio_ops wis_uda1342_audio_ops = {
+};
+
 static int wis_uda1342_command(struct i2c_client *client,
 				unsigned int cmd, void *arg)
 {
@@ -59,10 +67,16 @@ static int wis_uda1342_command(struct i2c_client *client,
 	return 0;
 }
 
+static const struct v4l2_subdev_ops wis_uda1342_ops = {
+//  .core = &wis_uda1342_core_ops,
+  .audio = &wis_uda1342_audio_ops,
+};
+
 static int wis_uda1342_probe(struct i2c_client *client,
 			     const struct i2c_device_id *id)
 {
 	struct i2c_adapter *adapter = client->adapter;
+  struct v4l2_subdev *sd;
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
 		return -ENODEV;
@@ -70,7 +84,11 @@ static int wis_uda1342_probe(struct i2c_client *client,
 	printk(KERN_DEBUG
 		"wis-uda1342: initializing UDA1342 at address %d on %s\n",
 		client->addr, adapter->name);
+  sd=kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+  if (sd == NULL)
+    return -ENOMEM;
 
+  v4l2_i2c_subdev_init(sd, client, &wis_uda1342_ops);
 	write_reg(client, 0x00, 0x8000); /* reset registers */
 	write_reg(client, 0x00, 0x1241); /* select input 1 */
 
@@ -79,6 +97,10 @@ static int wis_uda1342_probe(struct i2c_client *client,
 
 static int wis_uda1342_remove(struct i2c_client *client)
 {
+  struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+  v4l2_device_unregister_subdev(sd);
+  kfree(sd);
 	return 0;
 }
 

[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux