aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt856.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/bt856.c')
-rw-r--r--drivers/media/video/bt856.c218
1 files changed, 49 insertions, 169 deletions
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index ab2ce4d7b5de..4213867507f8 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -29,43 +29,24 @@
29 */ 29 */
30 30
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/delay.h>
34#include <linux/errno.h>
35#include <linux/fs.h>
36#include <linux/kernel.h>
37#include <linux/major.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/signal.h>
41#include <linux/types.h> 32#include <linux/types.h>
42#include <linux/i2c.h> 33#include <linux/ioctl.h>
43#include <linux/video_encoder.h>
44#include <asm/io.h>
45#include <asm/pgtable.h>
46#include <asm/page.h>
47#include <asm/uaccess.h> 34#include <asm/uaccess.h>
48 35#include <linux/i2c.h>
36#include <linux/i2c-id.h>
49#include <linux/videodev.h> 37#include <linux/videodev.h>
38#include <linux/video_encoder.h>
39#include <media/v4l2-common.h>
40#include <media/v4l2-i2c-drv-legacy.h>
50 41
51MODULE_DESCRIPTION("Brooktree-856A video encoder driver"); 42MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
52MODULE_AUTHOR("Mike Bernson & Dave Perks"); 43MODULE_AUTHOR("Mike Bernson & Dave Perks");
53MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
54 45
55
56#define I2C_NAME(s) (s)->name
57
58
59static int debug; 46static int debug;
60module_param(debug, int, 0); 47module_param(debug, int, 0);
61MODULE_PARM_DESC(debug, "Debug level (0-1)"); 48MODULE_PARM_DESC(debug, "Debug level (0-1)");
62 49
63#define dprintk(num, format, args...) \
64 do { \
65 if (debug >= num) \
66 printk(format, ##args); \
67 } while (0)
68
69/* ----------------------------------------------------------------------- */ 50/* ----------------------------------------------------------------------- */
70 51
71#define BT856_REG_OFFSET 0xDA 52#define BT856_REG_OFFSET 0xDA
@@ -78,14 +59,9 @@ struct bt856 {
78 int enable; 59 int enable;
79}; 60};
80 61
81#define I2C_BT856 0x88
82
83/* ----------------------------------------------------------------------- */ 62/* ----------------------------------------------------------------------- */
84 63
85static inline int 64static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
86bt856_write (struct i2c_client *client,
87 u8 reg,
88 u8 value)
89{ 65{
90 struct bt856 *encoder = i2c_get_clientdata(client); 66 struct bt856 *encoder = i2c_get_clientdata(client);
91 67
@@ -93,46 +69,36 @@ bt856_write (struct i2c_client *client,
93 return i2c_smbus_write_byte_data(client, reg, value); 69 return i2c_smbus_write_byte_data(client, reg, value);
94} 70}
95 71
96static inline int 72static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
97bt856_setbit (struct i2c_client *client,
98 u8 reg,
99 u8 bit,
100 u8 value)
101{ 73{
102 struct bt856 *encoder = i2c_get_clientdata(client); 74 struct bt856 *encoder = i2c_get_clientdata(client);
103 75
104 return bt856_write(client, reg, 76 return bt856_write(client, reg,
105 (encoder-> 77 (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
106 reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) | 78 (value ? (1 << bit) : 0));
107 (value ? (1 << bit) : 0));
108} 79}
109 80
110static void 81static void bt856_dump(struct i2c_client *client)
111bt856_dump (struct i2c_client *client)
112{ 82{
113 int i; 83 int i;
114 struct bt856 *encoder = i2c_get_clientdata(client); 84 struct bt856 *encoder = i2c_get_clientdata(client);
115 85
116 printk(KERN_INFO "%s: register dump:", I2C_NAME(client)); 86 v4l_info(client, "register dump:\n");
117 for (i = 0; i < BT856_NR_REG; i += 2) 87 for (i = 0; i < BT856_NR_REG; i += 2)
118 printk(" %02x", encoder->reg[i]); 88 printk(KERN_CONT " %02x", encoder->reg[i]);
119 printk("\n"); 89 printk(KERN_CONT "\n");
120} 90}
121 91
122/* ----------------------------------------------------------------------- */ 92/* ----------------------------------------------------------------------- */
123 93
124static int 94static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
125bt856_command (struct i2c_client *client,
126 unsigned int cmd,
127 void *arg)
128{ 95{
129 struct bt856 *encoder = i2c_get_clientdata(client); 96 struct bt856 *encoder = i2c_get_clientdata(client);
130 97
131 switch (cmd) { 98 switch (cmd) {
132
133 case 0: 99 case 0:
134 /* This is just for testing!!! */ 100 /* This is just for testing!!! */
135 dprintk(1, KERN_INFO "bt856: init\n"); 101 v4l_dbg(1, debug, client, "init\n");
136 bt856_write(client, 0xdc, 0x18); 102 bt856_write(client, 0xdc, 0x18);
137 bt856_write(client, 0xda, 0); 103 bt856_write(client, 0xda, 0);
138 bt856_write(client, 0xde, 0); 104 bt856_write(client, 0xde, 0);
@@ -142,7 +108,6 @@ bt856_command (struct i2c_client *client,
142 bt856_setbit(client, 0xdc, 4, 1); 108 bt856_setbit(client, 0xdc, 4, 1);
143 109
144 switch (encoder->norm) { 110 switch (encoder->norm) {
145
146 case VIDEO_MODE_NTSC: 111 case VIDEO_MODE_NTSC:
147 bt856_setbit(client, 0xdc, 2, 0); 112 bt856_setbit(client, 0xdc, 2, 0);
148 break; 113 break;
@@ -163,26 +128,23 @@ bt856_command (struct i2c_client *client,
163 { 128 {
164 struct video_encoder_capability *cap = arg; 129 struct video_encoder_capability *cap = arg;
165 130
166 dprintk(1, KERN_INFO "%s: get capabilities\n", 131 v4l_dbg(1, debug, client, "get capabilities\n");
167 I2C_NAME(client));
168 132
169 cap->flags = VIDEO_ENCODER_PAL | 133 cap->flags = VIDEO_ENCODER_PAL |
170 VIDEO_ENCODER_NTSC | 134 VIDEO_ENCODER_NTSC |
171 VIDEO_ENCODER_CCIR; 135 VIDEO_ENCODER_CCIR;
172 cap->inputs = 2; 136 cap->inputs = 2;
173 cap->outputs = 1; 137 cap->outputs = 1;
174 }
175 break; 138 break;
139 }
176 140
177 case ENCODER_SET_NORM: 141 case ENCODER_SET_NORM:
178 { 142 {
179 int *iarg = arg; 143 int *iarg = arg;
180 144
181 dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client), 145 v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
182 *iarg);
183 146
184 switch (*iarg) { 147 switch (*iarg) {
185
186 case VIDEO_MODE_NTSC: 148 case VIDEO_MODE_NTSC:
187 bt856_setbit(client, 0xdc, 2, 0); 149 bt856_setbit(client, 0xdc, 2, 0);
188 break; 150 break;
@@ -195,27 +157,23 @@ bt856_command (struct i2c_client *client,
195 157
196 default: 158 default:
197 return -EINVAL; 159 return -EINVAL;
198
199 } 160 }
200 encoder->norm = *iarg; 161 encoder->norm = *iarg;
201 if (debug != 0) 162 if (debug != 0)
202 bt856_dump(client); 163 bt856_dump(client);
203 }
204 break; 164 break;
165 }
205 166
206 case ENCODER_SET_INPUT: 167 case ENCODER_SET_INPUT:
207 { 168 {
208 int *iarg = arg; 169 int *iarg = arg;
209 170
210 dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client), 171 v4l_dbg(1, debug, client, "set input %d\n", *iarg);
211 *iarg);
212 172
213 /* We only have video bus. 173 /* We only have video bus.
214 * iarg = 0: input is from bt819 174 * iarg = 0: input is from bt819
215 * iarg = 1: input is from ZR36060 */ 175 * iarg = 1: input is from ZR36060 */
216
217 switch (*iarg) { 176 switch (*iarg) {
218
219 case 0: 177 case 0:
220 bt856_setbit(client, 0xde, 4, 0); 178 bt856_setbit(client, 0xde, 4, 0);
221 bt856_setbit(client, 0xde, 3, 1); 179 bt856_setbit(client, 0xde, 3, 1);
@@ -234,27 +192,24 @@ bt856_command (struct i2c_client *client,
234 break; 192 break;
235 default: 193 default:
236 return -EINVAL; 194 return -EINVAL;
237
238 } 195 }
239 196
240 if (debug != 0) 197 if (debug != 0)
241 bt856_dump(client); 198 bt856_dump(client);
242 }
243 break; 199 break;
200 }
244 201
245 case ENCODER_SET_OUTPUT: 202 case ENCODER_SET_OUTPUT:
246 { 203 {
247 int *iarg = arg; 204 int *iarg = arg;
248 205
249 dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client), 206 v4l_dbg(1, debug, client, "set output %d\n", *iarg);
250 *iarg);
251 207
252 /* not much choice of outputs */ 208 /* not much choice of outputs */
253 if (*iarg != 0) { 209 if (*iarg != 0)
254 return -EINVAL; 210 return -EINVAL;
255 }
256 }
257 break; 211 break;
212 }
258 213
259 case ENCODER_ENABLE_OUTPUT: 214 case ENCODER_ENABLE_OUTPUT:
260 { 215 {
@@ -262,10 +217,9 @@ bt856_command (struct i2c_client *client,
262 217
263 encoder->enable = !!*iarg; 218 encoder->enable = !!*iarg;
264 219
265 dprintk(1, KERN_INFO "%s: enable output %d\n", 220 v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
266 I2C_NAME(client), encoder->enable);
267 }
268 break; 221 break;
222 }
269 223
270 default: 224 default:
271 return -EINVAL; 225 return -EINVAL;
@@ -276,64 +230,29 @@ bt856_command (struct i2c_client *client,
276 230
277/* ----------------------------------------------------------------------- */ 231/* ----------------------------------------------------------------------- */
278 232
279/* 233static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
280 * Generic i2c probe
281 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
282 */
283static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
284
285static unsigned short ignore = I2C_CLIENT_END;
286
287static struct i2c_client_address_data addr_data = {
288 .normal_i2c = normal_i2c,
289 .probe = &ignore,
290 .ignore = &ignore,
291};
292 234
293static struct i2c_driver i2c_driver_bt856; 235I2C_CLIENT_INSMOD;
294 236
295static int 237static int bt856_probe(struct i2c_client *client,
296bt856_detect_client (struct i2c_adapter *adapter, 238 const struct i2c_device_id *id)
297 int address,
298 int kind)
299{ 239{
300 int i;
301 struct i2c_client *client;
302 struct bt856 *encoder; 240 struct bt856 *encoder;
303 241
304 dprintk(1,
305 KERN_INFO
306 "bt856.c: detecting bt856 client on address 0x%x\n",
307 address << 1);
308
309 /* Check if the adapter supports the needed features */ 242 /* Check if the adapter supports the needed features */
310 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 243 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
311 return 0; 244 return -ENODEV;
312 245
313 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 246 v4l_info(client, "chip found @ 0x%x (%s)\n",
314 if (!client) 247 client->addr << 1, client->adapter->name);
315 return -ENOMEM;
316 client->addr = address;
317 client->adapter = adapter;
318 client->driver = &i2c_driver_bt856;
319 strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
320 248
321 encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL); 249 encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
322 if (encoder == NULL) { 250 if (encoder == NULL)
323 kfree(client);
324 return -ENOMEM; 251 return -ENOMEM;
325 }
326 encoder->norm = VIDEO_MODE_NTSC; 252 encoder->norm = VIDEO_MODE_NTSC;
327 encoder->enable = 1; 253 encoder->enable = 1;
328 i2c_set_clientdata(client, encoder); 254 i2c_set_clientdata(client, encoder);
329 255
330 i = i2c_attach_client(client);
331 if (i) {
332 kfree(client);
333 kfree(encoder);
334 return i;
335 }
336
337 bt856_write(client, 0xdc, 0x18); 256 bt856_write(client, 0xdc, 0x18);
338 bt856_write(client, 0xda, 0); 257 bt856_write(client, 0xda, 0);
339 bt856_write(client, 0xde, 0); 258 bt856_write(client, 0xde, 0);
@@ -359,65 +278,26 @@ bt856_detect_client (struct i2c_adapter *adapter,
359 278
360 if (debug != 0) 279 if (debug != 0)
361 bt856_dump(client); 280 bt856_dump(client);
362
363 dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
364 client->addr << 1);
365
366 return 0; 281 return 0;
367} 282}
368 283
369static int 284static int bt856_remove(struct i2c_client *client)
370bt856_attach_adapter (struct i2c_adapter *adapter)
371{ 285{
372 dprintk(1, 286 kfree(i2c_get_clientdata(client));
373 KERN_INFO
374 "bt856.c: starting probe for adapter %s (0x%x)\n",
375 I2C_NAME(adapter), adapter->id);
376 return i2c_probe(adapter, &addr_data, &bt856_detect_client);
377}
378
379static int
380bt856_detach_client (struct i2c_client *client)
381{
382 struct bt856 *encoder = i2c_get_clientdata(client);
383 int err;
384
385 err = i2c_detach_client(client);
386 if (err) {
387 return err;
388 }
389
390 kfree(encoder);
391 kfree(client);
392
393 return 0; 287 return 0;
394} 288}
395 289
396/* ----------------------------------------------------------------------- */ 290static const struct i2c_device_id bt856_id[] = {
397 291 { "bt856", 0 },
398static struct i2c_driver i2c_driver_bt856 = { 292 { }
399 .driver = { 293};
400 .name = "bt856", 294MODULE_DEVICE_TABLE(i2c, bt856_id);
401 },
402
403 .id = I2C_DRIVERID_BT856,
404 295
405 .attach_adapter = bt856_attach_adapter, 296static struct v4l2_i2c_driver_data v4l2_i2c_data = {
406 .detach_client = bt856_detach_client, 297 .name = "bt856",
298 .driverid = I2C_DRIVERID_BT856,
407 .command = bt856_command, 299 .command = bt856_command,
300 .probe = bt856_probe,
301 .remove = bt856_remove,
302 .id_table = bt856_id,
408}; 303};
409
410static int __init
411bt856_init (void)
412{
413 return i2c_add_driver(&i2c_driver_bt856);
414}
415
416static void __exit
417bt856_exit (void)
418{
419 i2c_del_driver(&i2c_driver_bt856);
420}
421
422module_init(bt856_init);
423module_exit(bt856_exit);