aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/hdpvr/hdpvr-i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/hdpvr/hdpvr-i2c.c')
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c143
1 files changed, 67 insertions, 76 deletions
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index 24966aa02a70..89b71faeaac2 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -13,6 +13,8 @@
13 * 13 *
14 */ 14 */
15 15
16#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
17
16#include <linux/i2c.h> 18#include <linux/i2c.h>
17#include <linux/slab.h> 19#include <linux/slab.h>
18 20
@@ -28,106 +30,78 @@
28#define Z8F0811_IR_TX_I2C_ADDR 0x70 30#define Z8F0811_IR_TX_I2C_ADDR 0x70
29#define Z8F0811_IR_RX_I2C_ADDR 0x71 31#define Z8F0811_IR_RX_I2C_ADDR 0x71
30 32
31static const u8 ir_i2c_addrs[] = {
32 Z8F0811_IR_TX_I2C_ADDR,
33 Z8F0811_IR_RX_I2C_ADDR,
34};
35 33
36static const char * const ir_devicenames[] = { 34static struct i2c_board_info hdpvr_i2c_board_info = {
37 "ir_tx_z8f0811_hdpvr", 35 I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
38 "ir_rx_z8f0811_hdpvr", 36 I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
39}; 37};
40 38
41static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap, 39int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
42 const char *type, u8 addr)
43{ 40{
44 struct i2c_board_info info; 41 struct i2c_client *c;
45 struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data; 42 struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
46 unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
47
48 memset(&info, 0, sizeof(struct i2c_board_info));
49 strlcpy(info.type, type, I2C_NAME_SIZE);
50 43
51 /* Our default information for ir-kbd-i2c.c to use */ 44 /* Our default information for ir-kbd-i2c.c to use */
52 switch (addr) { 45 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
53 case Z8F0811_IR_RX_I2C_ADDR: 46 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
54 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 47 init_data->type = RC_TYPE_RC5;
55 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 48 init_data->name = "HD PVR";
56 init_data->type = RC_TYPE_RC5; 49 hdpvr_i2c_board_info.platform_data = init_data;
57 init_data->name = "HD PVR";
58 info.platform_data = init_data;
59 break;
60 }
61 50
62 return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? 51 c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
63 -1 : 0;
64}
65 52
66int hdpvr_register_i2c_ir(struct hdpvr_device *dev) 53 return (c == NULL) ? -ENODEV : 0;
67{
68 int i;
69 int ret = 0;
70
71 for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++)
72 ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter,
73 ir_devicenames[i], ir_i2c_addrs[i]);
74
75 return ret;
76} 54}
77 55
78static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, 56static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
79 char *data, int len) 57 unsigned char addr, char *data, int len)
80{ 58{
81 int ret; 59 int ret;
82 char *buf = kmalloc(len, GFP_KERNEL); 60
83 if (!buf) 61 if (len > sizeof(dev->i2c_buf))
84 return -ENOMEM; 62 return -EINVAL;
85 63
86 ret = usb_control_msg(dev->udev, 64 ret = usb_control_msg(dev->udev,
87 usb_rcvctrlpipe(dev->udev, 0), 65 usb_rcvctrlpipe(dev->udev, 0),
88 REQTYPE_I2C_READ, CTRL_READ_REQUEST, 66 REQTYPE_I2C_READ, CTRL_READ_REQUEST,
89 0x100|addr, 0, buf, len, 1000); 67 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
90 68
91 if (ret == len) { 69 if (ret == len) {
92 memcpy(data, buf, len); 70 memcpy(data, &dev->i2c_buf, len);
93 ret = 0; 71 ret = 0;
94 } else if (ret >= 0) 72 } else if (ret >= 0)
95 ret = -EIO; 73 ret = -EIO;
96 74
97 kfree(buf);
98
99 return ret; 75 return ret;
100} 76}
101 77
102static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr, 78static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
103 char *data, int len) 79 unsigned char addr, char *data, int len)
104{ 80{
105 int ret; 81 int ret;
106 char *buf = kmalloc(len, GFP_KERNEL);
107 if (!buf)
108 return -ENOMEM;
109 82
110 memcpy(buf, data, len); 83 if (len > sizeof(dev->i2c_buf))
84 return -EINVAL;
85
86 memcpy(&dev->i2c_buf, data, len);
111 ret = usb_control_msg(dev->udev, 87 ret = usb_control_msg(dev->udev,
112 usb_sndctrlpipe(dev->udev, 0), 88 usb_sndctrlpipe(dev->udev, 0),
113 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, 89 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
114 0x100|addr, 0, buf, len, 1000); 90 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
115 91
116 if (ret < 0) 92 if (ret < 0)
117 goto error; 93 return ret;
118 94
119 ret = usb_control_msg(dev->udev, 95 ret = usb_control_msg(dev->udev,
120 usb_rcvctrlpipe(dev->udev, 0), 96 usb_rcvctrlpipe(dev->udev, 0),
121 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, 97 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
122 0, 0, buf, 2, 1000); 98 0, 0, &dev->i2c_buf, 2, 1000);
123 99
124 if (ret == 2) 100 if ((ret == 2) && (dev->i2c_buf[1] == (len - 1)))
125 ret = 0; 101 ret = 0;
126 else if (ret >= 0) 102 else if (ret >= 0)
127 ret = -EIO; 103 ret = -EIO;
128 104
129error:
130 kfree(buf);
131 return ret; 105 return ret;
132} 106}
133 107
@@ -146,10 +120,10 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
146 addr = msgs[i].addr << 1; 120 addr = msgs[i].addr << 1;
147 121
148 if (msgs[i].flags & I2C_M_RD) 122 if (msgs[i].flags & I2C_M_RD)
149 retval = hdpvr_i2c_read(dev, addr, msgs[i].buf, 123 retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf,
150 msgs[i].len); 124 msgs[i].len);
151 else 125 else
152 retval = hdpvr_i2c_write(dev, addr, msgs[i].buf, 126 retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf,
153 msgs[i].len); 127 msgs[i].len);
154 } 128 }
155 129
@@ -168,30 +142,47 @@ static struct i2c_algorithm hdpvr_algo = {
168 .functionality = hdpvr_functionality, 142 .functionality = hdpvr_functionality,
169}; 143};
170 144
145static struct i2c_adapter hdpvr_i2c_adapter_template = {
146 .name = "Hauppage HD PVR I2C",
147 .owner = THIS_MODULE,
148 .algo = &hdpvr_algo,
149};
150
151static int hdpvr_activate_ir(struct hdpvr_device *dev)
152{
153 char buffer[8];
154
155 mutex_lock(&dev->i2c_mutex);
156
157 hdpvr_i2c_read(dev, 0, 0x54, buffer, 1);
158
159 buffer[0] = 0;
160 buffer[1] = 0x8;
161 hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
162
163 buffer[1] = 0x18;
164 hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
165
166 mutex_unlock(&dev->i2c_mutex);
167
168 return 0;
169}
170
171int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) 171int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
172{ 172{
173 struct i2c_adapter *i2c_adap;
174 int retval = -ENOMEM; 173 int retval = -ENOMEM;
175 174
176 i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); 175 hdpvr_activate_ir(dev);
177 if (i2c_adap == NULL)
178 goto error;
179
180 strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
181 sizeof(i2c_adap->name));
182 i2c_adap->algo = &hdpvr_algo;
183 i2c_adap->owner = THIS_MODULE;
184 i2c_adap->dev.parent = &dev->udev->dev;
185 176
186 i2c_set_adapdata(i2c_adap, dev); 177 memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template,
178 sizeof(struct i2c_adapter));
179 dev->i2c_adapter.dev.parent = &dev->udev->dev;
187 180
188 retval = i2c_add_adapter(i2c_adap); 181 i2c_set_adapdata(&dev->i2c_adapter, dev);
189 182
190 if (!retval) 183 retval = i2c_add_adapter(&dev->i2c_adapter);
191 dev->i2c_adapter = i2c_adap;
192 else
193 kfree(i2c_adap);
194 184
195error:
196 return retval; 185 return retval;
197} 186}
187
188#endif