diff options
Diffstat (limited to 'drivers/media/video/tea6415c.c')
-rw-r--r-- | drivers/media/video/tea6415c.c | 131 |
1 files changed, 40 insertions, 91 deletions
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 421c1445e96c..cde092adbb5a 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -2,6 +2,7 @@ | |||
2 | tea6415c - i2c-driver for the tea6415c by SGS Thomson | 2 | tea6415c - i2c-driver for the tea6415c by SGS Thomson |
3 | 3 | ||
4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> | 4 | Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> |
5 | Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl> | ||
5 | 6 | ||
6 | The tea6415c is a bus controlled video-matrix-switch | 7 | The tea6415c is a bus controlled video-matrix-switch |
7 | with 8 inputs and 6 outputs. | 8 | with 8 inputs and 6 outputs. |
@@ -30,18 +31,18 @@ | |||
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
31 | #include <linux/ioctl.h> | 32 | #include <linux/ioctl.h> |
32 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
33 | 34 | #include <media/v4l2-common.h> | |
35 | #include <media/v4l2-i2c-drv-legacy.h> | ||
34 | #include "tea6415c.h" | 36 | #include "tea6415c.h" |
35 | 37 | ||
36 | static int debug; /* insmod parameter */ | 38 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); |
37 | module_param(debug, int, 0644); | 39 | MODULE_DESCRIPTION("tea6415c driver"); |
38 | MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); | 40 | MODULE_LICENSE("GPL"); |
39 | 41 | ||
40 | #define dprintk(args...) \ | 42 | static int debug; |
41 | do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) | 43 | module_param(debug, int, 0644); |
42 | 44 | ||
43 | #define TEA6415C_NUM_INPUTS 8 | 45 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
44 | #define TEA6415C_NUM_OUTPUTS 6 | ||
45 | 46 | ||
46 | /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ | 47 | /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ |
47 | static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; | 48 | static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; |
@@ -49,60 +50,6 @@ static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIEN | |||
49 | /* magic definition of all other variables and things */ | 50 | /* magic definition of all other variables and things */ |
50 | I2C_CLIENT_INSMOD; | 51 | I2C_CLIENT_INSMOD; |
51 | 52 | ||
52 | static struct i2c_driver driver; | ||
53 | static struct i2c_client client_template; | ||
54 | |||
55 | /* this function is called by i2c_probe */ | ||
56 | static int detect(struct i2c_adapter *adapter, int address, int kind) | ||
57 | { | ||
58 | struct i2c_client *client = NULL; | ||
59 | int err = 0; | ||
60 | |||
61 | /* let's see whether this adapter can support what we need */ | ||
62 | if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* allocate memory for client structure */ | ||
67 | client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); | ||
68 | if (!client) { | ||
69 | return -ENOMEM; | ||
70 | } | ||
71 | |||
72 | /* fill client structure */ | ||
73 | memcpy(client, &client_template, sizeof(struct i2c_client)); | ||
74 | client->addr = address; | ||
75 | client->adapter = adapter; | ||
76 | |||
77 | /* tell the i2c layer a new client has arrived */ | ||
78 | if (0 != (err = i2c_attach_client(client))) { | ||
79 | kfree(client); | ||
80 | return err; | ||
81 | } | ||
82 | |||
83 | printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int attach(struct i2c_adapter *adapter) | ||
89 | { | ||
90 | /* let's see whether this is a know adapter we can attach to */ | ||
91 | if (adapter->id != I2C_HW_SAA7146) { | ||
92 | dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); | ||
93 | return -ENODEV; | ||
94 | } | ||
95 | |||
96 | return i2c_probe(adapter, &addr_data, &detect); | ||
97 | } | ||
98 | |||
99 | static int detach(struct i2c_client *client) | ||
100 | { | ||
101 | int ret = i2c_detach_client(client); | ||
102 | kfree(client); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | /* makes a connection between the input-pin 'i' and the output-pin 'o' | 53 | /* makes a connection between the input-pin 'i' and the output-pin 'o' |
107 | for the tea6415c-client 'client' */ | 54 | for the tea6415c-client 'client' */ |
108 | static int switch_matrix(struct i2c_client *client, int i, int o) | 55 | static int switch_matrix(struct i2c_client *client, int i, int o) |
@@ -110,7 +57,7 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
110 | u8 byte = 0; | 57 | u8 byte = 0; |
111 | int ret; | 58 | int ret; |
112 | 59 | ||
113 | dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); | 60 | v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o); |
114 | 61 | ||
115 | /* check if the pins are valid */ | 62 | /* check if the pins are valid */ |
116 | if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) | 63 | if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) |
@@ -168,14 +115,14 @@ static int switch_matrix(struct i2c_client *client, int i, int o) | |||
168 | 115 | ||
169 | ret = i2c_smbus_write_byte(client, byte); | 116 | ret = i2c_smbus_write_byte(client, byte); |
170 | if (ret) { | 117 | if (ret) { |
171 | dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); | 118 | v4l_dbg(1, debug, client, |
119 | "i2c_smbus_write_byte() failed, ret:%d\n", ret); | ||
172 | return -EIO; | 120 | return -EIO; |
173 | } | 121 | } |
174 | |||
175 | return ret; | 122 | return ret; |
176 | } | 123 | } |
177 | 124 | ||
178 | static int command(struct i2c_client *client, unsigned int cmd, void *arg) | 125 | static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg) |
179 | { | 126 | { |
180 | struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; | 127 | struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; |
181 | int result = 0; | 128 | int result = 0; |
@@ -187,38 +134,40 @@ static int command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
187 | default: | 134 | default: |
188 | return -ENOIOCTLCMD; | 135 | return -ENOIOCTLCMD; |
189 | } | 136 | } |
190 | |||
191 | return result; | 137 | return result; |
192 | } | 138 | } |
193 | 139 | ||
194 | static struct i2c_driver driver = { | 140 | /* this function is called by i2c_probe */ |
195 | .driver = { | 141 | static int tea6415c_probe(struct i2c_client *client, |
196 | .name = "tea6415c", | 142 | const struct i2c_device_id *id) |
197 | }, | ||
198 | .id = I2C_DRIVERID_TEA6415C, | ||
199 | .attach_adapter = attach, | ||
200 | .detach_client = detach, | ||
201 | .command = command, | ||
202 | }; | ||
203 | |||
204 | static struct i2c_client client_template = { | ||
205 | .name = "tea6415c", | ||
206 | .driver = &driver, | ||
207 | }; | ||
208 | |||
209 | static int __init this_module_init(void) | ||
210 | { | 143 | { |
211 | return i2c_add_driver(&driver); | 144 | /* let's see whether this adapter can support what we need */ |
145 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) | ||
146 | return 0; | ||
147 | |||
148 | v4l_info(client, "chip found @ 0x%x (%s)\n", | ||
149 | client->addr << 1, client->adapter->name); | ||
150 | return 0; | ||
212 | } | 151 | } |
213 | 152 | ||
214 | static void __exit this_module_exit(void) | 153 | static int tea6415c_legacy_probe(struct i2c_adapter *adapter) |
215 | { | 154 | { |
216 | i2c_del_driver(&driver); | 155 | /* Let's see whether this is a known adapter we can attach to. |
156 | Prevents conflicts with tvaudio.c. */ | ||
157 | return adapter->id == I2C_HW_SAA7146; | ||
217 | } | 158 | } |
218 | 159 | ||
219 | module_init(this_module_init); | 160 | static const struct i2c_device_id tea6415c_id[] = { |
220 | module_exit(this_module_exit); | 161 | { "tea6415c", 0 }, |
162 | { } | ||
163 | }; | ||
164 | MODULE_DEVICE_TABLE(i2c, tea6415c_id); | ||
221 | 165 | ||
222 | MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); | 166 | static struct v4l2_i2c_driver_data v4l2_i2c_data = { |
223 | MODULE_DESCRIPTION("tea6415c driver"); | 167 | .name = "tea6415c", |
224 | MODULE_LICENSE("GPL"); | 168 | .driverid = I2C_DRIVERID_TEA6415C, |
169 | .command = tea6415c_command, | ||
170 | .probe = tea6415c_probe, | ||
171 | .legacy_probe = tea6415c_legacy_probe, | ||
172 | .id_table = tea6415c_id, | ||
173 | }; | ||