summaryrefslogtreecommitdiffstats
path: root/hdpvr-ir-enable.patch
blob: a5c7e922ca8a952742f0e047cda281b8a9b94e44 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
diff -Naurp a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
--- a/drivers/media/video/hdpvr/hdpvr-core.c	2010-07-06 17:36:44.000000000 -0400
+++ b/drivers/media/video/hdpvr/hdpvr-core.c	2010-07-06 17:38:13.000000000 -0400
@@ -363,9 +363,8 @@ static int hdpvr_probe(struct usb_interf
 		goto error;
 	}
 
-#ifdef CONFIG_I2C
-	/* until i2c is working properly */
-	retval = 0; /* hdpvr_register_i2c_adapter(dev); */
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+	retval = hdpvr_register_i2c_adapter(dev);
 	if (retval < 0) {
 		v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
 		goto error;
@@ -411,12 +410,9 @@ static void hdpvr_disconnect(struct usb_
 	mutex_unlock(&dev->io_mutex);
 
 	/* deregister I2C adapter */
-#ifdef CONFIG_I2C
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 	mutex_lock(&dev->i2c_mutex);
-	if (dev->i2c_adapter)
-		i2c_del_adapter(dev->i2c_adapter);
-	kfree(dev->i2c_adapter);
-	dev->i2c_adapter = NULL;
+	i2c_del_adapter(&dev->i2c_adapter);
 	mutex_unlock(&dev->i2c_mutex);
 #endif /* CONFIG_I2C */
 
diff -Naurp a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
--- a/drivers/media/video/hdpvr/hdpvr.h	2010-02-24 13:52:17.000000000 -0500
+++ b/drivers/media/video/hdpvr/hdpvr.h	2010-07-06 17:42:20.000000000 -0400
@@ -101,7 +101,7 @@ struct hdpvr_device {
 	struct work_struct	worker;
 
 	/* I2C adapter */
-	struct i2c_adapter	*i2c_adapter;
+	struct i2c_adapter	i2c_adapter;
 	/* I2C lock */
 	struct mutex		i2c_mutex;
 
diff -Naurp a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c	2010-07-06 17:36:51.000000000 -0400
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c	2010-07-06 17:45:50.000000000 -0400
@@ -10,6 +10,8 @@
  *
  */
 
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+
 #include <linux/i2c.h>
 
 #include "hdpvr.h"
@@ -19,10 +21,13 @@
 
 #define REQTYPE_I2C_READ	0xb1
 #define REQTYPE_I2C_WRITE	0xb0
-#define REQTYPE_I2C_WRITE_STATT	0xd0
+#define REQTYPE_I2C_WRITE_STAT	0xd0
+
+#define HDPVR_HW_Z8F0811_IR_TX_I2C_ADDR	0x70
+#define HDPVR_HW_Z8F0811_IR_RX_I2C_ADDR	0x71
 
 static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
-			  char *data, int len)
+			  char *data, int len, int bus)
 {
 	int ret;
 	char *buf = kmalloc(len, GFP_KERNEL);
@@ -32,7 +37,7 @@ static int hdpvr_i2c_read(struct hdpvr_d
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
 			      REQTYPE_I2C_READ, CTRL_READ_REQUEST,
-			      0x100|addr, 0, buf, len, 1000);
+			      bus<<8 | addr, 0, buf, len, 1000);
 
 	if (ret == len) {
 		memcpy(data, buf, len);
@@ -46,7 +51,7 @@ static int hdpvr_i2c_read(struct hdpvr_d
 }
 
 static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
-			   char *data, int len)
+			   char *data, int len, int bus)
 {
 	int ret;
 	char *buf = kmalloc(len, GFP_KERNEL);
@@ -57,17 +62,17 @@ static int hdpvr_i2c_write(struct hdpvr_
 	ret = usb_control_msg(dev->udev,
 			      usb_sndctrlpipe(dev->udev, 0),
 			      REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
-			      0x100|addr, 0, buf, len, 1000);
+			      bus<<8 | addr, 0, buf, len, 1000);
 
 	if (ret < 0)
 		goto error;
 
 	ret = usb_control_msg(dev->udev,
 			      usb_rcvctrlpipe(dev->udev, 0),
-			      REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
+			      REQTYPE_I2C_WRITE_STAT, CTRL_READ_REQUEST,
 			      0, 0, buf, 2, 1000);
 
-	if (ret == 2)
+	if (ret == 2 && buf[1] == (len - 1))
 		ret = 0;
 	else if (ret >= 0)
 		ret = -EIO;
@@ -93,10 +98,10 @@ static int hdpvr_transfer(struct i2c_ada
 
 		if (msgs[i].flags & I2C_M_RD)
 			retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
-						msgs[i].len);
+						msgs[i].len, 1);
 		else
 			retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
-						 msgs[i].len);
+						 msgs[i].len, 1);
 	}
 
 	mutex_unlock(&dev->i2c_mutex);
@@ -114,31 +119,61 @@ static struct i2c_algorithm hdpvr_algo =
 	.functionality = hdpvr_functionality,
 };
 
+static struct i2c_adapter hdpvr_i2c_adap_template = {
+	.name		= "Hauppauge HD PVR I2C",
+	.owner		= THIS_MODULE,
+	.id		= I2C_HW_B_HDPVR,
+	.algo		= &hdpvr_algo,
+	.algo_data	= NULL,
+	.class		= I2C_CLASS_TV_ANALOG,
+};
+
+static struct i2c_board_info hdpvr_i2c_board_info = {
+	I2C_BOARD_INFO("ir_tx_z8f0811_haup", HDPVR_HW_Z8F0811_IR_TX_I2C_ADDR),
+	I2C_BOARD_INFO("ir_rx_z8f0811_haup", HDPVR_HW_Z8F0811_IR_RX_I2C_ADDR),
+};
+
+static int hdpvr_activate_ir(struct hdpvr_device *dev)
+{
+	char buffer[8];
+
+	mutex_lock(&dev->i2c_mutex);
+
+	hdpvr_i2c_read(dev, 0x54, buffer, 1, 0);
+
+	buffer[0] = 0;
+	buffer[1] = 0x8;
+	hdpvr_i2c_write(dev, 0x54, buffer, 2, 1);
+
+	buffer[1] = 0x18;
+	hdpvr_i2c_write(dev, 0x54, buffer, 2, 1);
+
+	mutex_unlock(&dev->i2c_mutex);
+	return 0;
+}
+
+
 int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
 {
-	struct i2c_adapter *i2c_adap;
 	int retval = -ENOMEM;
 
-	i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (i2c_adap == NULL)
+	hdpvr_activate_ir(dev);
+
+	memcpy(&dev->i2c_adapter, &hdpvr_i2c_adap_template,
+	       sizeof(struct i2c_adapter));
+	dev->i2c_adapter.dev.parent = &dev->udev->dev;
+
+	i2c_set_adapdata(&dev->i2c_adapter, dev);
+
+	retval = i2c_add_adapter(&dev->i2c_adapter);
+
+	if (retval)
 		goto error;
 
-	strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
-		sizeof(i2c_adap->name));
-	i2c_adap->algo  = &hdpvr_algo;
-	i2c_adap->class = I2C_CLASS_TV_ANALOG;
-	i2c_adap->owner = THIS_MODULE;
-	i2c_adap->dev.parent = &dev->udev->dev;
-
-	i2c_set_adapdata(i2c_adap, dev);
-
-	retval = i2c_add_adapter(i2c_adap);
-
-	if (!retval)
-		dev->i2c_adapter = i2c_adap;
-	else
-		kfree(i2c_adap);
+	i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
 
 error:
 	return retval;
 }
+
+#endif /* CONFIG_I2C */
diff -Naurp a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile
--- a/drivers/media/video/hdpvr/Makefile	2010-07-06 17:36:38.000000000 -0400
+++ b/drivers/media/video/hdpvr/Makefile	2010-07-06 17:35:17.000000000 -0400
@@ -1,6 +1,4 @@
-hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-video.o
-
-hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
+hdpvr-objs	:= hdpvr-control.o hdpvr-core.o hdpvr-i2c.o hdpvr-video.o
 
 obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o