OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [media/] [video/] [bt856.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * bt856 - BT856A Digital Video Encoder (Rockwell Part)
3
 *
4
 * Copyright (C) 1999 Mike Bernson <mike@mlb.org>
5
 * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
6
 *
7
 * Modifications for LML33/DC10plus unified driver
8
 * Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
9
 *
10
 * This code was modify/ported from the saa7111 driver written
11
 * by Dave Perks.
12
 *
13
 * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
14
 *   - moved over to linux>=2.4.x i2c protocol (9/9/2002)
15
 *
16
 * This program is free software; you can redistribute it and/or modify
17
 * it under the terms of the GNU General Public License as published by
18
 * the Free Software Foundation; either version 2 of the License, or
19
 * (at your option) any later version.
20
 *
21
 * This program is distributed in the hope that it will be useful,
22
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 * GNU General Public License for more details.
25
 *
26
 * You should have received a copy of the GNU General Public License
27
 * along with this program; if not, write to the Free Software
28
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29
 */
30
 
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>
42
#include <linux/i2c.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>
48
 
49
#include <linux/videodev.h>
50
 
51
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
52
MODULE_AUTHOR("Mike Bernson & Dave Perks");
53
MODULE_LICENSE("GPL");
54
 
55
 
56
#define I2C_NAME(s) (s)->name
57
 
58
 
59
static int debug = 0;
60
module_param(debug, int, 0);
61
MODULE_PARM_DESC(debug, "Debug level (0-1)");
62
 
63
#define dprintk(num, format, args...) \
64
        do { \
65
                if (debug >= num) \
66
                        printk(format, ##args); \
67
        } while (0)
68
 
69
/* ----------------------------------------------------------------------- */
70
 
71
#define REG_OFFSET      0xDA
72
#define BT856_NR_REG    6
73
 
74
struct bt856 {
75
        unsigned char reg[BT856_NR_REG];
76
 
77
        int norm;
78
        int enable;
79
};
80
 
81
#define   I2C_BT856        0x88
82
 
83
/* ----------------------------------------------------------------------- */
84
 
85
static inline int
86
bt856_write (struct i2c_client *client,
87
             u8                 reg,
88
             u8                 value)
89
{
90
        struct bt856 *encoder = i2c_get_clientdata(client);
91
 
92
        encoder->reg[reg - REG_OFFSET] = value;
93
        return i2c_smbus_write_byte_data(client, reg, value);
94
}
95
 
96
static inline int
97
bt856_setbit (struct i2c_client *client,
98
              u8                 reg,
99
              u8                 bit,
100
              u8                 value)
101
{
102
        struct bt856 *encoder = i2c_get_clientdata(client);
103
 
104
        return bt856_write(client, reg,
105
                           (encoder->
106
                            reg[reg - REG_OFFSET] & ~(1 << bit)) |
107
                            (value ? (1 << bit) : 0));
108
}
109
 
110
static void
111
bt856_dump (struct i2c_client *client)
112
{
113
        int i;
114
        struct bt856 *encoder = i2c_get_clientdata(client);
115
 
116
        printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
117
        for (i = 0; i < BT856_NR_REG; i += 2)
118
                printk(" %02x", encoder->reg[i]);
119
        printk("\n");
120
}
121
 
122
/* ----------------------------------------------------------------------- */
123
 
124
static int
125
bt856_command (struct i2c_client *client,
126
               unsigned int       cmd,
127
               void              *arg)
128
{
129
        struct bt856 *encoder = i2c_get_clientdata(client);
130
 
131
        switch (cmd) {
132
 
133
        case 0:
134
                /* This is just for testing!!! */
135
                dprintk(1, KERN_INFO "bt856: init\n");
136
                bt856_write(client, 0xdc, 0x18);
137
                bt856_write(client, 0xda, 0);
138
                bt856_write(client, 0xde, 0);
139
 
140
                bt856_setbit(client, 0xdc, 3, 1);
141
                //bt856_setbit(client, 0xdc, 6, 0);
142
                bt856_setbit(client, 0xdc, 4, 1);
143
 
144
                switch (encoder->norm) {
145
 
146
                case VIDEO_MODE_NTSC:
147
                        bt856_setbit(client, 0xdc, 2, 0);
148
                        break;
149
 
150
                case VIDEO_MODE_PAL:
151
                        bt856_setbit(client, 0xdc, 2, 1);
152
                        break;
153
                }
154
 
155
                bt856_setbit(client, 0xdc, 1, 1);
156
                bt856_setbit(client, 0xde, 4, 0);
157
                bt856_setbit(client, 0xde, 3, 1);
158
                if (debug != 0)
159
                        bt856_dump(client);
160
                break;
161
 
162
        case ENCODER_GET_CAPABILITIES:
163
        {
164
                struct video_encoder_capability *cap = arg;
165
 
166
                dprintk(1, KERN_INFO "%s: get capabilities\n",
167
                        I2C_NAME(client));
168
 
169
                cap->flags = VIDEO_ENCODER_PAL |
170
                             VIDEO_ENCODER_NTSC |
171
                             VIDEO_ENCODER_CCIR;
172
                cap->inputs = 2;
173
                cap->outputs = 1;
174
        }
175
                break;
176
 
177
        case ENCODER_SET_NORM:
178
        {
179
                int *iarg = arg;
180
 
181
                dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
182
                        *iarg);
183
 
184
                switch (*iarg) {
185
 
186
                case VIDEO_MODE_NTSC:
187
                        bt856_setbit(client, 0xdc, 2, 0);
188
                        break;
189
 
190
                case VIDEO_MODE_PAL:
191
                        bt856_setbit(client, 0xdc, 2, 1);
192
                        bt856_setbit(client, 0xda, 0, 0);
193
                        //bt856_setbit(client, 0xda, 0, 1);
194
                        break;
195
 
196
                default:
197
                        return -EINVAL;
198
 
199
                }
200
                encoder->norm = *iarg;
201
                if (debug != 0)
202
                        bt856_dump(client);
203
        }
204
                break;
205
 
206
        case ENCODER_SET_INPUT:
207
        {
208
                int *iarg = arg;
209
 
210
                dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
211
                        *iarg);
212
 
213
                /* We only have video bus.
214
                 * iarg = 0: input is from bt819
215
                 * iarg = 1: input is from ZR36060 */
216
 
217
                switch (*iarg) {
218
 
219
                case 0:
220
                        bt856_setbit(client, 0xde, 4, 0);
221
                        bt856_setbit(client, 0xde, 3, 1);
222
                        bt856_setbit(client, 0xdc, 3, 1);
223
                        bt856_setbit(client, 0xdc, 6, 0);
224
                        break;
225
                case 1:
226
                        bt856_setbit(client, 0xde, 4, 0);
227
                        bt856_setbit(client, 0xde, 3, 1);
228
                        bt856_setbit(client, 0xdc, 3, 1);
229
                        bt856_setbit(client, 0xdc, 6, 1);
230
                        break;
231
                case 2: // Color bar
232
                        bt856_setbit(client, 0xdc, 3, 0);
233
                        bt856_setbit(client, 0xde, 4, 1);
234
                        break;
235
                default:
236
                        return -EINVAL;
237
 
238
                }
239
 
240
                if (debug != 0)
241
                        bt856_dump(client);
242
        }
243
                break;
244
 
245
        case ENCODER_SET_OUTPUT:
246
        {
247
                int *iarg = arg;
248
 
249
                dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
250
                        *iarg);
251
 
252
                /* not much choice of outputs */
253
                if (*iarg != 0) {
254
                        return -EINVAL;
255
                }
256
        }
257
                break;
258
 
259
        case ENCODER_ENABLE_OUTPUT:
260
        {
261
                int *iarg = arg;
262
 
263
                encoder->enable = !!*iarg;
264
 
265
                dprintk(1, KERN_INFO "%s: enable output %d\n",
266
                        I2C_NAME(client), encoder->enable);
267
        }
268
                break;
269
 
270
        default:
271
                return -EINVAL;
272
        }
273
 
274
        return 0;
275
}
276
 
277
/* ----------------------------------------------------------------------- */
278
 
279
/*
280
 * Generic i2c probe
281
 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
282
 */
283
static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
284
 
285
static unsigned short ignore = I2C_CLIENT_END;
286
 
287
static struct i2c_client_address_data addr_data = {
288
        .normal_i2c             = normal_i2c,
289
        .probe                  = &ignore,
290
        .ignore                 = &ignore,
291
};
292
 
293
static struct i2c_driver i2c_driver_bt856;
294
 
295
static int
296
bt856_detect_client (struct i2c_adapter *adapter,
297
                     int                 address,
298
                     int                 kind)
299
{
300
        int i;
301
        struct i2c_client *client;
302
        struct bt856 *encoder;
303
 
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 */
310
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
311
                return 0;
312
 
313
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
314
        if (client == 0)
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
 
321
        encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
322
        if (encoder == NULL) {
323
                kfree(client);
324
                return -ENOMEM;
325
        }
326
        encoder->norm = VIDEO_MODE_NTSC;
327
        encoder->enable = 1;
328
        i2c_set_clientdata(client, encoder);
329
 
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);
338
        bt856_write(client, 0xda, 0);
339
        bt856_write(client, 0xde, 0);
340
 
341
        bt856_setbit(client, 0xdc, 3, 1);
342
        //bt856_setbit(client, 0xdc, 6, 0);
343
        bt856_setbit(client, 0xdc, 4, 1);
344
 
345
        switch (encoder->norm) {
346
 
347
        case VIDEO_MODE_NTSC:
348
                bt856_setbit(client, 0xdc, 2, 0);
349
                break;
350
 
351
        case VIDEO_MODE_PAL:
352
                bt856_setbit(client, 0xdc, 2, 1);
353
                break;
354
        }
355
 
356
        bt856_setbit(client, 0xdc, 1, 1);
357
        bt856_setbit(client, 0xde, 4, 0);
358
        bt856_setbit(client, 0xde, 3, 1);
359
 
360
        if (debug != 0)
361
                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;
367
}
368
 
369
static int
370
bt856_attach_adapter (struct i2c_adapter *adapter)
371
{
372
        dprintk(1,
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
 
379
static int
380
bt856_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;
394
}
395
 
396
/* ----------------------------------------------------------------------- */
397
 
398
static struct i2c_driver i2c_driver_bt856 = {
399
        .driver = {
400
                .name = "bt856",
401
        },
402
 
403
        .id = I2C_DRIVERID_BT856,
404
 
405
        .attach_adapter = bt856_attach_adapter,
406
        .detach_client = bt856_detach_client,
407
        .command = bt856_command,
408
};
409
 
410
static int __init
411
bt856_init (void)
412
{
413
        return i2c_add_driver(&i2c_driver_bt856);
414
}
415
 
416
static void __exit
417
bt856_exit (void)
418
{
419
        i2c_del_driver(&i2c_driver_bt856);
420
}
421
 
422
module_init(bt856_init);
423
module_exit(bt856_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.