This source file includes following definitions.
- to_saa7110
- to_sd
- saa7110_write
- saa7110_write_block
- saa7110_read
- saa7110_selmux
- determine_norm
- saa7110_g_input_status
- saa7110_querystd
- saa7110_s_std
- saa7110_s_routing
- saa7110_s_stream
- saa7110_s_ctrl
- saa7110_probe
- saa7110_remove
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/types.h>
18 #include <linux/delay.h>
19 #include <linux/slab.h>
20 #include <linux/wait.h>
21 #include <linux/uaccess.h>
22 #include <linux/i2c.h>
23 #include <linux/videodev2.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-ctrls.h>
26
27 MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
28 MODULE_AUTHOR("Pauline Middelink");
29 MODULE_LICENSE("GPL");
30
31
32 static int debug;
33 module_param(debug, int, 0);
34 MODULE_PARM_DESC(debug, "Debug level (0-1)");
35
36 #define SAA7110_MAX_INPUT 9
37 #define SAA7110_MAX_OUTPUT 1
38
39 #define SAA7110_NR_REG 0x35
40
41 struct saa7110 {
42 struct v4l2_subdev sd;
43 struct v4l2_ctrl_handler hdl;
44 u8 reg[SAA7110_NR_REG];
45
46 v4l2_std_id norm;
47 int input;
48 int enable;
49
50 wait_queue_head_t wq;
51 };
52
53 static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
54 {
55 return container_of(sd, struct saa7110, sd);
56 }
57
58 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
59 {
60 return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
61 }
62
63
64
65
66
67 static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
68 {
69 struct i2c_client *client = v4l2_get_subdevdata(sd);
70 struct saa7110 *decoder = to_saa7110(sd);
71
72 decoder->reg[reg] = value;
73 return i2c_smbus_write_byte_data(client, reg, value);
74 }
75
76 static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
77 {
78 struct i2c_client *client = v4l2_get_subdevdata(sd);
79 struct saa7110 *decoder = to_saa7110(sd);
80 int ret = -1;
81 u8 reg = *data;
82
83
84 if (reg + (len - 1) > SAA7110_NR_REG)
85 return ret;
86
87
88
89 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
90 ret = i2c_master_send(client, data, len);
91
92
93 memcpy(decoder->reg + reg, data + 1, len - 1);
94 } else {
95 for (++data, --len; len; len--) {
96 ret = saa7110_write(sd, reg++, *data++);
97 if (ret < 0)
98 break;
99 }
100 }
101
102 return ret;
103 }
104
105 static inline int saa7110_read(struct v4l2_subdev *sd)
106 {
107 struct i2c_client *client = v4l2_get_subdevdata(sd);
108
109 return i2c_smbus_read_byte(client);
110 }
111
112
113
114
115
116 #define FRESP_06H_COMPST 0x03
117 #define FRESP_06H_SVIDEO 0x83
118
119
120 static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
121 {
122 static const unsigned char modes[9][8] = {
123
124 {FRESP_06H_COMPST, 0xD9, 0x17, 0x40, 0x03,
125 0x44, 0x75, 0x16},
126
127 {FRESP_06H_COMPST, 0xD8, 0x17, 0x40, 0x03,
128 0x44, 0x75, 0x16},
129
130 {FRESP_06H_COMPST, 0xBA, 0x07, 0x91, 0x03,
131 0x60, 0xB5, 0x05},
132
133 {FRESP_06H_COMPST, 0xB8, 0x07, 0x91, 0x03,
134 0x60, 0xB5, 0x05},
135
136 {FRESP_06H_COMPST, 0x7C, 0x07, 0xD2, 0x83,
137 0x60, 0xB5, 0x03},
138
139 {FRESP_06H_COMPST, 0x78, 0x07, 0xD2, 0x83,
140 0x60, 0xB5, 0x03},
141
142 {FRESP_06H_SVIDEO, 0x59, 0x17, 0x42, 0xA3,
143 0x44, 0x75, 0x12},
144
145 {FRESP_06H_SVIDEO, 0x9A, 0x17, 0xB1, 0x13,
146 0x60, 0xB5, 0x14},
147
148 {FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
149 0x44, 0x75, 0x21}
150 };
151 struct saa7110 *decoder = to_saa7110(sd);
152 const unsigned char *ptr = modes[chan];
153
154 saa7110_write(sd, 0x06, ptr[0]);
155 saa7110_write(sd, 0x20, ptr[1]);
156 saa7110_write(sd, 0x21, ptr[2]);
157 saa7110_write(sd, 0x22, ptr[3]);
158 saa7110_write(sd, 0x2C, ptr[4]);
159 saa7110_write(sd, 0x30, ptr[5]);
160 saa7110_write(sd, 0x31, ptr[6]);
161 saa7110_write(sd, 0x21, ptr[7]);
162 decoder->input = chan;
163
164 return 0;
165 }
166
167 static const unsigned char initseq[1 + SAA7110_NR_REG] = {
168 0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF2, 0x03, 0x00,
169 0xF8, 0xF8, 0x60, 0x60, 0x00, 0x86, 0x18, 0x90,
170 0x00, 0x59, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
171 0xF2, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0xD9, 0x16, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
173 0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x03, 0x0C,
174 0x44, 0x71, 0x02, 0x8C, 0x02
175 };
176
177 static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
178 {
179 DEFINE_WAIT(wait);
180 struct saa7110 *decoder = to_saa7110(sd);
181 int status;
182
183
184 saa7110_write_block(sd, initseq, sizeof(initseq));
185 saa7110_selmux(sd, decoder->input);
186 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
187 schedule_timeout(msecs_to_jiffies(250));
188 finish_wait(&decoder->wq, &wait);
189 status = saa7110_read(sd);
190 if (status & 0x40) {
191 v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
192 return V4L2_STD_UNKNOWN;
193 }
194 if ((status & 3) == 0) {
195 saa7110_write(sd, 0x06, 0x83);
196 if (status & 0x20) {
197 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
198
199 return V4L2_STD_NTSC;
200 }
201 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
202
203 return V4L2_STD_PAL;
204 }
205
206 if (status & 0x20) {
207 v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
208 saa7110_write(sd, 0x0D, 0x86);
209 saa7110_write(sd, 0x0F, 0x50);
210 saa7110_write(sd, 0x11, 0x2C);
211
212 return V4L2_STD_NTSC;
213 }
214
215
216 saa7110_write(sd, 0x0D, 0x86);
217 saa7110_write(sd, 0x0F, 0x10);
218 saa7110_write(sd, 0x11, 0x59);
219
220
221 prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
222 schedule_timeout(msecs_to_jiffies(250));
223 finish_wait(&decoder->wq, &wait);
224
225 status = saa7110_read(sd);
226 if ((status & 0x03) == 0x01) {
227 v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
228 saa7110_write(sd, 0x0D, 0x87);
229 return V4L2_STD_SECAM;
230 }
231 v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
232 return V4L2_STD_PAL;
233 }
234
235 static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
236 {
237 struct saa7110 *decoder = to_saa7110(sd);
238 int res = V4L2_IN_ST_NO_SIGNAL;
239 int status = saa7110_read(sd);
240
241 v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
242 status, (unsigned long long)decoder->norm);
243 if (!(status & 0x40))
244 res = 0;
245 if (!(status & 0x03))
246 res |= V4L2_IN_ST_NO_COLOR;
247
248 *pstatus = res;
249 return 0;
250 }
251
252 static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
253 {
254 *std &= determine_norm(sd);
255 return 0;
256 }
257
258 static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
259 {
260 struct saa7110 *decoder = to_saa7110(sd);
261
262 if (decoder->norm != std) {
263 decoder->norm = std;
264
265 if (std & V4L2_STD_NTSC) {
266 saa7110_write(sd, 0x0D, 0x86);
267 saa7110_write(sd, 0x0F, 0x50);
268 saa7110_write(sd, 0x11, 0x2C);
269
270 v4l2_dbg(1, debug, sd, "switched to NTSC\n");
271 } else if (std & V4L2_STD_PAL) {
272 saa7110_write(sd, 0x0D, 0x86);
273 saa7110_write(sd, 0x0F, 0x10);
274 saa7110_write(sd, 0x11, 0x59);
275
276 v4l2_dbg(1, debug, sd, "switched to PAL\n");
277 } else if (std & V4L2_STD_SECAM) {
278 saa7110_write(sd, 0x0D, 0x87);
279 saa7110_write(sd, 0x0F, 0x10);
280 saa7110_write(sd, 0x11, 0x59);
281
282 v4l2_dbg(1, debug, sd, "switched to SECAM\n");
283 } else {
284 return -EINVAL;
285 }
286 }
287 return 0;
288 }
289
290 static int saa7110_s_routing(struct v4l2_subdev *sd,
291 u32 input, u32 output, u32 config)
292 {
293 struct saa7110 *decoder = to_saa7110(sd);
294
295 if (input >= SAA7110_MAX_INPUT) {
296 v4l2_dbg(1, debug, sd, "input=%d not available\n", input);
297 return -EINVAL;
298 }
299 if (decoder->input != input) {
300 saa7110_selmux(sd, input);
301 v4l2_dbg(1, debug, sd, "switched to input=%d\n", input);
302 }
303 return 0;
304 }
305
306 static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
307 {
308 struct saa7110 *decoder = to_saa7110(sd);
309
310 if (decoder->enable != enable) {
311 decoder->enable = enable;
312 saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
313 v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
314 }
315 return 0;
316 }
317
318 static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
319 {
320 struct v4l2_subdev *sd = to_sd(ctrl);
321
322 switch (ctrl->id) {
323 case V4L2_CID_BRIGHTNESS:
324 saa7110_write(sd, 0x19, ctrl->val);
325 break;
326 case V4L2_CID_CONTRAST:
327 saa7110_write(sd, 0x13, ctrl->val);
328 break;
329 case V4L2_CID_SATURATION:
330 saa7110_write(sd, 0x12, ctrl->val);
331 break;
332 case V4L2_CID_HUE:
333 saa7110_write(sd, 0x07, ctrl->val);
334 break;
335 default:
336 return -EINVAL;
337 }
338 return 0;
339 }
340
341
342
343 static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
344 .s_ctrl = saa7110_s_ctrl,
345 };
346
347 static const struct v4l2_subdev_video_ops saa7110_video_ops = {
348 .s_std = saa7110_s_std,
349 .s_routing = saa7110_s_routing,
350 .s_stream = saa7110_s_stream,
351 .querystd = saa7110_querystd,
352 .g_input_status = saa7110_g_input_status,
353 };
354
355 static const struct v4l2_subdev_ops saa7110_ops = {
356 .video = &saa7110_video_ops,
357 };
358
359
360
361 static int saa7110_probe(struct i2c_client *client,
362 const struct i2c_device_id *id)
363 {
364 struct saa7110 *decoder;
365 struct v4l2_subdev *sd;
366 int rv;
367
368
369 if (!i2c_check_functionality(client->adapter,
370 I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
371 return -ENODEV;
372
373 v4l_info(client, "chip found @ 0x%x (%s)\n",
374 client->addr << 1, client->adapter->name);
375
376 decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
377 if (!decoder)
378 return -ENOMEM;
379 sd = &decoder->sd;
380 v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
381 decoder->norm = V4L2_STD_PAL;
382 decoder->input = 0;
383 decoder->enable = 1;
384 v4l2_ctrl_handler_init(&decoder->hdl, 2);
385 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
386 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
387 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
388 V4L2_CID_CONTRAST, 0, 127, 1, 64);
389 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
390 V4L2_CID_SATURATION, 0, 127, 1, 64);
391 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
392 V4L2_CID_HUE, -128, 127, 1, 0);
393 sd->ctrl_handler = &decoder->hdl;
394 if (decoder->hdl.error) {
395 int err = decoder->hdl.error;
396
397 v4l2_ctrl_handler_free(&decoder->hdl);
398 return err;
399 }
400 v4l2_ctrl_handler_setup(&decoder->hdl);
401
402 init_waitqueue_head(&decoder->wq);
403
404 rv = saa7110_write_block(sd, initseq, sizeof(initseq));
405 if (rv < 0) {
406 v4l2_dbg(1, debug, sd, "init status %d\n", rv);
407 } else {
408 int ver, status;
409 saa7110_write(sd, 0x21, 0x10);
410 saa7110_write(sd, 0x0e, 0x18);
411 saa7110_write(sd, 0x0D, 0x04);
412 ver = saa7110_read(sd);
413 saa7110_write(sd, 0x0D, 0x06);
414
415 status = saa7110_read(sd);
416 v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
417 ver, status);
418 saa7110_write(sd, 0x0D, 0x86);
419 saa7110_write(sd, 0x0F, 0x10);
420 saa7110_write(sd, 0x11, 0x59);
421
422 }
423
424
425
426
427
428 return 0;
429 }
430
431 static int saa7110_remove(struct i2c_client *client)
432 {
433 struct v4l2_subdev *sd = i2c_get_clientdata(client);
434 struct saa7110 *decoder = to_saa7110(sd);
435
436 v4l2_device_unregister_subdev(sd);
437 v4l2_ctrl_handler_free(&decoder->hdl);
438 return 0;
439 }
440
441
442
443 static const struct i2c_device_id saa7110_id[] = {
444 { "saa7110", 0 },
445 { }
446 };
447 MODULE_DEVICE_TABLE(i2c, saa7110_id);
448
449 static struct i2c_driver saa7110_driver = {
450 .driver = {
451 .name = "saa7110",
452 },
453 .probe = saa7110_probe,
454 .remove = saa7110_remove,
455 .id_table = saa7110_id,
456 };
457
458 module_i2c_driver(saa7110_driver);