This source file includes following definitions.
- to_saa7185
- saa7185_read
- saa7185_write
- saa7185_write_block
- saa7185_init
- saa7185_s_std_output
- saa7185_s_routing
- saa7185_probe
- saa7185_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include <linux/module.h>
15 #include <linux/types.h>
16 #include <linux/slab.h>
17 #include <linux/ioctl.h>
18 #include <linux/uaccess.h>
19 #include <linux/i2c.h>
20 #include <linux/videodev2.h>
21 #include <media/v4l2-device.h>
22
23 MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
24 MODULE_AUTHOR("Dave Perks");
25 MODULE_LICENSE("GPL");
26
27 static int debug;
28 module_param(debug, int, 0);
29 MODULE_PARM_DESC(debug, "Debug level (0-1)");
30
31
32
33
34 struct saa7185 {
35 struct v4l2_subdev sd;
36 unsigned char reg[128];
37
38 v4l2_std_id norm;
39 };
40
41 static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd)
42 {
43 return container_of(sd, struct saa7185, sd);
44 }
45
46
47
48 static inline int saa7185_read(struct v4l2_subdev *sd)
49 {
50 struct i2c_client *client = v4l2_get_subdevdata(sd);
51
52 return i2c_smbus_read_byte(client);
53 }
54
55 static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value)
56 {
57 struct i2c_client *client = v4l2_get_subdevdata(sd);
58 struct saa7185 *encoder = to_saa7185(sd);
59
60 v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value);
61 encoder->reg[reg] = value;
62 return i2c_smbus_write_byte_data(client, reg, value);
63 }
64
65 static int saa7185_write_block(struct v4l2_subdev *sd,
66 const u8 *data, unsigned int len)
67 {
68 struct i2c_client *client = v4l2_get_subdevdata(sd);
69 struct saa7185 *encoder = to_saa7185(sd);
70 int ret = -1;
71 u8 reg;
72
73
74
75 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
76
77 u8 block_data[32];
78 int block_len;
79
80 while (len >= 2) {
81 block_len = 0;
82 block_data[block_len++] = reg = data[0];
83 do {
84 block_data[block_len++] =
85 encoder->reg[reg++] = data[1];
86 len -= 2;
87 data += 2;
88 } while (len >= 2 && data[0] == reg && block_len < 32);
89 ret = i2c_master_send(client, block_data, block_len);
90 if (ret < 0)
91 break;
92 }
93 } else {
94
95 while (len >= 2) {
96 reg = *data++;
97 ret = saa7185_write(sd, reg, *data++);
98 if (ret < 0)
99 break;
100 len -= 2;
101 }
102 }
103
104 return ret;
105 }
106
107
108
109 static const unsigned char init_common[] = {
110 0x3a, 0x0f,
111
112
113 0x42, 0x6b,
114 0x43, 0x00,
115 0x44, 0x00,
116 0x45, 0x22,
117 0x46, 0xac,
118 0x47, 0x0e,
119 0x48, 0x03,
120 0x49, 0x1d,
121 0x4a, 0xac,
122 0x4b, 0xf0,
123 0x4c, 0xc8,
124 0x4d, 0xb9,
125 0x4e, 0xd4,
126 0x4f, 0x38,
127 0x50, 0x47,
128 0x51, 0xc1,
129 0x52, 0xe3,
130 0x53, 0x54,
131 0x54, 0xa3,
132 0x55, 0x54,
133 0x56, 0xf2,
134 0x57, 0x90,
135 0x58, 0x00,
136 0x59, 0x00,
137
138 0x5a, 0x00,
139 0x5b, 0x76,
140 0x5c, 0xa5,
141 0x5d, 0x3c,
142 0x5e, 0x3a,
143 0x5f, 0x3a,
144 0x60, 0x00,
145
146
147
148 0x67, 0x00,
149 0x68, 0x00,
150 0x69, 0x00,
151 0x6a, 0x00,
152
153 0x6b, 0x91,
154 0x6c, 0x20,
155
156 0x6d, 0x00,
157
158 0x6e, 0x0e,
159
160 0x6f, 0x00,
161 0x70, 0x20,
162
163
164
165 0x71, 0x15,
166 0x72, 0x90,
167 0x73, 0x61,
168 0x74, 0x00,
169 0x75, 0x00,
170 0x76, 0x00,
171 0x77, 0x15,
172 0x78, 0x90,
173 0x79, 0x61,
174
175
176
177 0x7a, 0x70,
178
179
180
181 0x7b, 0x16,
182 0x7c, 0x35,
183 0x7d, 0x20,
184 };
185
186 static const unsigned char init_pal[] = {
187 0x61, 0x1e,
188
189 0x62, 0xc8,
190 0x63, 0xcb,
191 0x64, 0x8a,
192 0x65, 0x09,
193 0x66, 0x2a,
194 };
195
196 static const unsigned char init_ntsc[] = {
197 0x61, 0x1d,
198
199 0x62, 0xe6,
200 0x63, 0x1f,
201 0x64, 0x7c,
202 0x65, 0xf0,
203 0x66, 0x21,
204 };
205
206
207 static int saa7185_init(struct v4l2_subdev *sd, u32 val)
208 {
209 struct saa7185 *encoder = to_saa7185(sd);
210
211 saa7185_write_block(sd, init_common, sizeof(init_common));
212 if (encoder->norm & V4L2_STD_NTSC)
213 saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
214 else
215 saa7185_write_block(sd, init_pal, sizeof(init_pal));
216 return 0;
217 }
218
219 static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
220 {
221 struct saa7185 *encoder = to_saa7185(sd);
222
223 if (std & V4L2_STD_NTSC)
224 saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
225 else if (std & V4L2_STD_PAL)
226 saa7185_write_block(sd, init_pal, sizeof(init_pal));
227 else
228 return -EINVAL;
229 encoder->norm = std;
230 return 0;
231 }
232
233 static int saa7185_s_routing(struct v4l2_subdev *sd,
234 u32 input, u32 output, u32 config)
235 {
236 struct saa7185 *encoder = to_saa7185(sd);
237
238
239
240
241 switch (input) {
242 case 0:
243
244 saa7185_write(sd, 0x3a, 0x0f);
245
246 saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
247 saa7185_write(sd, 0x6e, 0x01);
248 break;
249
250 case 1:
251
252 saa7185_write(sd, 0x3a, 0x0f);
253
254 saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
255
256 saa7185_write(sd, 0x6e, 0x00);
257 break;
258
259 case 2:
260
261 saa7185_write(sd, 0x3a, 0x8f);
262
263 saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
264
265 saa7185_write(sd, 0x6e, 0x01);
266 break;
267
268 default:
269 return -EINVAL;
270 }
271 return 0;
272 }
273
274
275
276 static const struct v4l2_subdev_core_ops saa7185_core_ops = {
277 .init = saa7185_init,
278 };
279
280 static const struct v4l2_subdev_video_ops saa7185_video_ops = {
281 .s_std_output = saa7185_s_std_output,
282 .s_routing = saa7185_s_routing,
283 };
284
285 static const struct v4l2_subdev_ops saa7185_ops = {
286 .core = &saa7185_core_ops,
287 .video = &saa7185_video_ops,
288 };
289
290
291
292
293 static int saa7185_probe(struct i2c_client *client,
294 const struct i2c_device_id *id)
295 {
296 int i;
297 struct saa7185 *encoder;
298 struct v4l2_subdev *sd;
299
300
301 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
302 return -ENODEV;
303
304 v4l_info(client, "chip found @ 0x%x (%s)\n",
305 client->addr << 1, client->adapter->name);
306
307 encoder = devm_kzalloc(&client->dev, sizeof(*encoder), GFP_KERNEL);
308 if (encoder == NULL)
309 return -ENOMEM;
310 encoder->norm = V4L2_STD_NTSC;
311 sd = &encoder->sd;
312 v4l2_i2c_subdev_init(sd, client, &saa7185_ops);
313
314 i = saa7185_write_block(sd, init_common, sizeof(init_common));
315 if (i >= 0)
316 i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
317 if (i < 0)
318 v4l2_dbg(1, debug, sd, "init error %d\n", i);
319 else
320 v4l2_dbg(1, debug, sd, "revision 0x%x\n",
321 saa7185_read(sd) >> 5);
322 return 0;
323 }
324
325 static int saa7185_remove(struct i2c_client *client)
326 {
327 struct v4l2_subdev *sd = i2c_get_clientdata(client);
328 struct saa7185 *encoder = to_saa7185(sd);
329
330 v4l2_device_unregister_subdev(sd);
331
332 saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
333 return 0;
334 }
335
336
337
338 static const struct i2c_device_id saa7185_id[] = {
339 { "saa7185", 0 },
340 { }
341 };
342 MODULE_DEVICE_TABLE(i2c, saa7185_id);
343
344 static struct i2c_driver saa7185_driver = {
345 .driver = {
346 .name = "saa7185",
347 },
348 .probe = saa7185_probe,
349 .remove = saa7185_remove,
350 .id_table = saa7185_id,
351 };
352
353 module_i2c_driver(saa7185_driver);