[media] hdpvr: enable IR part
[deliverable/linux.git] / drivers / media / video / hdpvr / hdpvr-i2c.c
CommitLineData
9aba42ef
JG
1
2/*
e86da6f0 3 * Hauppauge HD PVR USB driver
9aba42ef
JG
4 *
5 * Copyright (C) 2008 Janne Grunau (j@jannau.net)
6 *
ea6c0603
AW
7 * IR device registration code is
8 * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.net>
9 *
9aba42ef
JG
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation, version 2.
13 *
14 */
15
324b04ba
JW
16#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
17
9aba42ef 18#include <linux/i2c.h>
5a0e3ad6 19#include <linux/slab.h>
9aba42ef
JG
20
21#include "hdpvr.h"
22
23#define CTRL_READ_REQUEST 0xb8
24#define CTRL_WRITE_REQUEST 0x38
25
26#define REQTYPE_I2C_READ 0xb1
27#define REQTYPE_I2C_WRITE 0xb0
28#define REQTYPE_I2C_WRITE_STATT 0xd0
29
ea6c0603
AW
30#define Z8F0811_IR_TX_I2C_ADDR 0x70
31#define Z8F0811_IR_RX_I2C_ADDR 0x71
32
ea6c0603 33
324b04ba
JW
34static struct i2c_board_info hdpvr_i2c_board_info = {
35 I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
36 I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
ea6c0603
AW
37};
38
324b04ba 39int hdpvr_register_i2c_ir(struct hdpvr_device *dev)
ea6c0603 40{
324b04ba 41 struct i2c_client *c;
ea6c0603 42 struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
ea6c0603
AW
43
44 /* Our default information for ir-kbd-i2c.c to use */
324b04ba
JW
45 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW;
46 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
47 init_data->type = RC_TYPE_RC5;
48 init_data->name = "HD PVR";
49 hdpvr_i2c_board_info.platform_data = init_data;
ea6c0603 50
324b04ba 51 c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info);
ea6c0603 52
324b04ba 53 return (c == NULL) ? -ENODEV : 0;
ea6c0603
AW
54}
55
324b04ba
JW
56static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
57 unsigned char addr, char *data, int len)
9aba42ef
JG
58{
59 int ret;
60 char *buf = kmalloc(len, GFP_KERNEL);
61 if (!buf)
62 return -ENOMEM;
63
64 ret = usb_control_msg(dev->udev,
65 usb_rcvctrlpipe(dev->udev, 0),
66 REQTYPE_I2C_READ, CTRL_READ_REQUEST,
324b04ba 67 (bus << 8) | addr, 0, buf, len, 1000);
9aba42ef
JG
68
69 if (ret == len) {
70 memcpy(data, buf, len);
71 ret = 0;
72 } else if (ret >= 0)
73 ret = -EIO;
74
75 kfree(buf);
76
77 return ret;
78}
79
324b04ba
JW
80static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
81 unsigned char addr, char *data, int len)
9aba42ef
JG
82{
83 int ret;
84 char *buf = kmalloc(len, GFP_KERNEL);
85 if (!buf)
86 return -ENOMEM;
87
88 memcpy(buf, data, len);
89 ret = usb_control_msg(dev->udev,
90 usb_sndctrlpipe(dev->udev, 0),
91 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
324b04ba 92 (bus << 8) | addr, 0, buf, len, 1000);
9aba42ef
JG
93
94 if (ret < 0)
95 goto error;
96
97 ret = usb_control_msg(dev->udev,
98 usb_rcvctrlpipe(dev->udev, 0),
99 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
100 0, 0, buf, 2, 1000);
101
324b04ba 102 if ((ret == 2) && (buf[1] == (len - 1)))
9aba42ef
JG
103 ret = 0;
104 else if (ret >= 0)
105 ret = -EIO;
106
107error:
108 kfree(buf);
109 return ret;
110}
111
112static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
113 int num)
114{
115 struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
116 int retval = 0, i, addr;
117
118 if (num <= 0)
119 return 0;
120
121 mutex_lock(&dev->i2c_mutex);
122
123 for (i = 0; i < num && !retval; i++) {
124 addr = msgs[i].addr << 1;
125
126 if (msgs[i].flags & I2C_M_RD)
324b04ba 127 retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf,
9aba42ef
JG
128 msgs[i].len);
129 else
324b04ba 130 retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf,
9aba42ef
JG
131 msgs[i].len);
132 }
133
134 mutex_unlock(&dev->i2c_mutex);
135
136 return retval ? retval : num;
137}
138
139static u32 hdpvr_functionality(struct i2c_adapter *adapter)
140{
141 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
142}
143
144static struct i2c_algorithm hdpvr_algo = {
145 .master_xfer = hdpvr_transfer,
146 .functionality = hdpvr_functionality,
147};
148
324b04ba
JW
149static struct i2c_adapter hdpvr_i2c_adapter_template = {
150 .name = "Hauppage HD PVR I2C",
151 .owner = THIS_MODULE,
152 .algo = &hdpvr_algo,
153};
154
155static int hdpvr_activate_ir(struct hdpvr_device *dev)
156{
157 char buffer[8];
158
159 mutex_lock(&dev->i2c_mutex);
160
161 hdpvr_i2c_read(dev, 0, 0x54, buffer, 1);
162
163 buffer[0] = 0;
164 buffer[1] = 0x8;
165 hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
166
167 buffer[1] = 0x18;
168 hdpvr_i2c_write(dev, 1, 0x54, buffer, 2);
169
170 mutex_unlock(&dev->i2c_mutex);
171
172 return 0;
173}
174
9aba42ef
JG
175int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
176{
9aba42ef
JG
177 int retval = -ENOMEM;
178
324b04ba 179 hdpvr_activate_ir(dev);
9aba42ef 180
324b04ba
JW
181 memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template,
182 sizeof(struct i2c_adapter));
183 dev->i2c_adapter.dev.parent = &dev->udev->dev;
9aba42ef 184
324b04ba 185 i2c_set_adapdata(&dev->i2c_adapter, dev);
9aba42ef 186
324b04ba 187 retval = i2c_add_adapter(&dev->i2c_adapter);
9aba42ef 188
9aba42ef
JG
189 return retval;
190}
324b04ba
JW
191
192#endif
This page took 0.536408 seconds and 5 git commands to generate.