Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/video/bt856.c
17498 views
1
/*
2
* bt856 - BT856A Digital Video Encoder (Rockwell Part)
3
*
4
* Copyright (C) 1999 Mike Bernson <[email protected]>
5
* Copyright (C) 1998 Dave Perks <[email protected]>
6
*
7
* Modifications for LML33/DC10plus unified driver
8
* Copyright (C) 2000 Serguei Miridonov <[email protected]>
9
*
10
* This code was modify/ported from the saa7111 driver written
11
* by Dave Perks.
12
*
13
* Changes by Ronald Bultje <[email protected]>
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/types.h>
33
#include <linux/slab.h>
34
#include <linux/ioctl.h>
35
#include <asm/uaccess.h>
36
#include <linux/i2c.h>
37
#include <linux/videodev2.h>
38
#include <media/v4l2-device.h>
39
#include <media/v4l2-chip-ident.h>
40
41
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
42
MODULE_AUTHOR("Mike Bernson & Dave Perks");
43
MODULE_LICENSE("GPL");
44
45
static int debug;
46
module_param(debug, int, 0);
47
MODULE_PARM_DESC(debug, "Debug level (0-1)");
48
49
50
/* ----------------------------------------------------------------------- */
51
52
#define BT856_REG_OFFSET 0xDA
53
#define BT856_NR_REG 6
54
55
struct bt856 {
56
struct v4l2_subdev sd;
57
unsigned char reg[BT856_NR_REG];
58
59
v4l2_std_id norm;
60
};
61
62
static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
63
{
64
return container_of(sd, struct bt856, sd);
65
}
66
67
/* ----------------------------------------------------------------------- */
68
69
static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value)
70
{
71
struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
72
73
encoder->reg[reg - BT856_REG_OFFSET] = value;
74
return i2c_smbus_write_byte_data(client, reg, value);
75
}
76
77
static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value)
78
{
79
return bt856_write(encoder, reg,
80
(encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
81
(value ? (1 << bit) : 0));
82
}
83
84
static void bt856_dump(struct bt856 *encoder)
85
{
86
int i;
87
88
v4l2_info(&encoder->sd, "register dump:\n");
89
for (i = 0; i < BT856_NR_REG; i += 2)
90
printk(KERN_CONT " %02x", encoder->reg[i]);
91
printk(KERN_CONT "\n");
92
}
93
94
/* ----------------------------------------------------------------------- */
95
96
static int bt856_init(struct v4l2_subdev *sd, u32 arg)
97
{
98
struct bt856 *encoder = to_bt856(sd);
99
100
/* This is just for testing!!! */
101
v4l2_dbg(1, debug, sd, "init\n");
102
bt856_write(encoder, 0xdc, 0x18);
103
bt856_write(encoder, 0xda, 0);
104
bt856_write(encoder, 0xde, 0);
105
106
bt856_setbit(encoder, 0xdc, 3, 1);
107
/*bt856_setbit(encoder, 0xdc, 6, 0);*/
108
bt856_setbit(encoder, 0xdc, 4, 1);
109
110
if (encoder->norm & V4L2_STD_NTSC)
111
bt856_setbit(encoder, 0xdc, 2, 0);
112
else
113
bt856_setbit(encoder, 0xdc, 2, 1);
114
115
bt856_setbit(encoder, 0xdc, 1, 1);
116
bt856_setbit(encoder, 0xde, 4, 0);
117
bt856_setbit(encoder, 0xde, 3, 1);
118
if (debug != 0)
119
bt856_dump(encoder);
120
return 0;
121
}
122
123
static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
124
{
125
struct bt856 *encoder = to_bt856(sd);
126
127
v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
128
129
if (std & V4L2_STD_NTSC) {
130
bt856_setbit(encoder, 0xdc, 2, 0);
131
} else if (std & V4L2_STD_PAL) {
132
bt856_setbit(encoder, 0xdc, 2, 1);
133
bt856_setbit(encoder, 0xda, 0, 0);
134
/*bt856_setbit(encoder, 0xda, 0, 1);*/
135
} else {
136
return -EINVAL;
137
}
138
encoder->norm = std;
139
if (debug != 0)
140
bt856_dump(encoder);
141
return 0;
142
}
143
144
static int bt856_s_routing(struct v4l2_subdev *sd,
145
u32 input, u32 output, u32 config)
146
{
147
struct bt856 *encoder = to_bt856(sd);
148
149
v4l2_dbg(1, debug, sd, "set input %d\n", input);
150
151
/* We only have video bus.
152
* input= 0: input is from bt819
153
* input= 1: input is from ZR36060 */
154
switch (input) {
155
case 0:
156
bt856_setbit(encoder, 0xde, 4, 0);
157
bt856_setbit(encoder, 0xde, 3, 1);
158
bt856_setbit(encoder, 0xdc, 3, 1);
159
bt856_setbit(encoder, 0xdc, 6, 0);
160
break;
161
case 1:
162
bt856_setbit(encoder, 0xde, 4, 0);
163
bt856_setbit(encoder, 0xde, 3, 1);
164
bt856_setbit(encoder, 0xdc, 3, 1);
165
bt856_setbit(encoder, 0xdc, 6, 1);
166
break;
167
case 2: /* Color bar */
168
bt856_setbit(encoder, 0xdc, 3, 0);
169
bt856_setbit(encoder, 0xde, 4, 1);
170
break;
171
default:
172
return -EINVAL;
173
}
174
175
if (debug != 0)
176
bt856_dump(encoder);
177
return 0;
178
}
179
180
static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
181
{
182
struct i2c_client *client = v4l2_get_subdevdata(sd);
183
184
return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
185
}
186
187
/* ----------------------------------------------------------------------- */
188
189
static const struct v4l2_subdev_core_ops bt856_core_ops = {
190
.g_chip_ident = bt856_g_chip_ident,
191
.init = bt856_init,
192
};
193
194
static const struct v4l2_subdev_video_ops bt856_video_ops = {
195
.s_std_output = bt856_s_std_output,
196
.s_routing = bt856_s_routing,
197
};
198
199
static const struct v4l2_subdev_ops bt856_ops = {
200
.core = &bt856_core_ops,
201
.video = &bt856_video_ops,
202
};
203
204
/* ----------------------------------------------------------------------- */
205
206
static int bt856_probe(struct i2c_client *client,
207
const struct i2c_device_id *id)
208
{
209
struct bt856 *encoder;
210
struct v4l2_subdev *sd;
211
212
/* Check if the adapter supports the needed features */
213
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
214
return -ENODEV;
215
216
v4l_info(client, "chip found @ 0x%x (%s)\n",
217
client->addr << 1, client->adapter->name);
218
219
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
220
if (encoder == NULL)
221
return -ENOMEM;
222
sd = &encoder->sd;
223
v4l2_i2c_subdev_init(sd, client, &bt856_ops);
224
encoder->norm = V4L2_STD_NTSC;
225
226
bt856_write(encoder, 0xdc, 0x18);
227
bt856_write(encoder, 0xda, 0);
228
bt856_write(encoder, 0xde, 0);
229
230
bt856_setbit(encoder, 0xdc, 3, 1);
231
/*bt856_setbit(encoder, 0xdc, 6, 0);*/
232
bt856_setbit(encoder, 0xdc, 4, 1);
233
234
if (encoder->norm & V4L2_STD_NTSC)
235
bt856_setbit(encoder, 0xdc, 2, 0);
236
else
237
bt856_setbit(encoder, 0xdc, 2, 1);
238
239
bt856_setbit(encoder, 0xdc, 1, 1);
240
bt856_setbit(encoder, 0xde, 4, 0);
241
bt856_setbit(encoder, 0xde, 3, 1);
242
243
if (debug != 0)
244
bt856_dump(encoder);
245
return 0;
246
}
247
248
static int bt856_remove(struct i2c_client *client)
249
{
250
struct v4l2_subdev *sd = i2c_get_clientdata(client);
251
252
v4l2_device_unregister_subdev(sd);
253
kfree(to_bt856(sd));
254
return 0;
255
}
256
257
static const struct i2c_device_id bt856_id[] = {
258
{ "bt856", 0 },
259
{ }
260
};
261
MODULE_DEVICE_TABLE(i2c, bt856_id);
262
263
static struct i2c_driver bt856_driver = {
264
.driver = {
265
.owner = THIS_MODULE,
266
.name = "bt856",
267
},
268
.probe = bt856_probe,
269
.remove = bt856_remove,
270
.id_table = bt856_id,
271
};
272
273
static __init int init_bt856(void)
274
{
275
return i2c_add_driver(&bt856_driver);
276
}
277
278
static __exit void exit_bt856(void)
279
{
280
i2c_del_driver(&bt856_driver);
281
}
282
283
module_init(init_bt856);
284
module_exit(exit_bt856);
285
286